2015-02-04 2 views
0

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

До здания с дистилляционными работами (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 

ответ

0

Существует проблема связывания, когда исходный код 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  
0

Существует опечатка в структуре samplemodule. Название модуля - «образец», а не «samle»

Смежные вопросы