Расширение C-API Python 3 ImportError

Я использую Python3 на Mac OS X 10.10.2. Я новичок в Python C-API, поэтому я пробую простой пример расширения C-API из "Python Cookbook" http://chimera.labs.oreilly.com/books/1230000000393/ch15.html. Я думаю, что есть некоторая разница между Python2 и Python3. Я следовал за документацией Python3, но не могу найти, почему мой случай не работает.

До здания с перегонками работает (python3 setup.py build или же python3 setup.py build_ext --inplace) давая мне sample.so файл. Я скомпилировал sample.c а также получение sample.o,

Но когда я импортирую из python, я получаю сообщение об ошибке, как показано ниже, и я не понимаю, что происходит. Ниже показано сообщение об ошибке запуска в ipython3.

Пожалуйста, помогите мне с этим вопросом расширения модулей. Спасибо!

In [1]: import sample
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-6-a769eab12f54> in <module>()
----> 1 import sample

ImportError: dlopen(/Users/suh/pyLNKS/python-api-example/sample/sample.so, 2): Symbol not found: _gcd
Referenced from: /Users/suh/pyLNKS/python-api-example/sample/sample.so
Expected in: flat namespace
in /Users/suh/pyLNKS/python-api-example/sample/sample.so

In [2]:

Ниже приведены коды для файлов pysample.c, sample.c, sample.h, а также setup.py,

pysample.c

1 #include <Python.h>
2 #include "sample.h"
3 
4 
5 static PyObject *py_gcd(PyObject *self, PyObject *args) {
6     int x, y, result;
7 
8     if (!PyArg_ParseTuple(args, "ii", &x, &y)) {
9         return NULL;
10     }
11     result = gcd(x, y);
12     return Py_BuildValue("i", result);
13 }
14 
15 
16 /* module method table */
17 static PyMethodDef SampleMethods[] = {
18     {"gcd", py_gcd, METH_VARARGS, "Greatest commond divisor"},
19    // {"divide", py_divide, METH_VARARGS, "Integer division"},
20     {NULL, NULL, 0, NULL}
21 };
22 
23 static struct PyModuleDef samplemodule = {
24     PyModuleDef_HEAD_INIT,
25     "samle",    /* name of module */
26     "A sample module",  /* doc string, may be NULL */
27     -1, /* size of per-interpreter state of the module, 
28            or -1 if the module keeps state in global variables */
29     SampleMethods   /* methods table */
30 };  
31 
32 PyMODINIT_FUNC
33 PyInit_sample(void){
34     return PyModule_Create(&samplemodule);
35 }   
36     

sample.c

1 /* sample.c */
2 #include <math.h>
3 
4 /* compute the greatest common divisor */
5 int gcd(int x, int y){
6     int g = y;
7     while (x > 0){
8         g = x;
9         x = y % x;
10         y = g;
11     }
12     return g;
13 }

sample.h

1 /* sample.h */
2 #include <math.h>
3 
4 extern int gcd(int x, int y);

setup.py

1 # setup.py
2 from distutils.core import setup, Extension
3 
4 module1 = Extension('sample', sources = ['pysample.c'])
5 
6 setup(name='simple',
7         version = '1.0',
8         description = "this is a demo package",
9         ext_modules = [module1]
10         )
11 

2 ответа

В структуре образца модуля есть опечатка. Название модуля - "образец", а не "samle"

Существует проблема со связыванием, когда исходный код sample.c не связан, так что функция gcd не определена.

Таким образом, код setup.py необходимо изменить на:

1 # setup.py
2 from distutils.core import setup, Extension
3 
4 module1 = Extension('sample', sources = ['pysample.c','source.c'])
5 
6 setup(name='simple',
7         version = '1.0',
8         description = "this is a demo package",
9         ext_modules = [module1]
10         )
11    
Другие вопросы по тегам