2017-10-17 95 views
1

我试图建立用C Python模块,并停留在一个问题:定制的C模块包括

当我包括额外的头文件(test.h),模块编译没有警告,但后来import这个模块,Python抱怨未定义的符号maketest

我的模块结构如下(模块被命名为spam):

内容的 spammodule.c
spam\ 
    ├spammodule.c 
    |setup.py 
    ├─src\ 
     |── test.c 
     |── test.h 

#include <Python.h> 
#include "test.h" 

static PyObject * SpamError; 

static PyObject * 
spam_system(PyObject *self, PyObject *args) 
{ 
    const char *command; 
    int sts; 

    maketest(); // <---- calling function from additional file 

    if(!PyArg_ParseTuple(args, "s", &command)) 
     return NULL; 

    sts = system(command); 
    if (sts < 0) { 
     PyErr_SetString(SpamError, "System command failed"); 
     return NULL; 
    } 
    return PyLong_FromLong(sts); 
} 

PyMODINIT_FUNC 
initspam(void) 
{ 
    PyObject *m; 
    static PyMethodDef SpamMethods[] = { 
     {"system", spam_system, METH_VARARGS, "Execute a shell command."}, 
     {NULL, NULL, 0, NULL} 
    }; 
    m = Py_InitModule("spam", SpamMethods); 
    if (m == NULL) 
     return; 

    SpamError = PyErr_NewException("spam.error", NULL, NULL); 
    Py_INCREF(SpamError); 
    PyModule_AddObject(m, "error", SpamError); 
} 

int 
main(int argc, char *argv[]) 
{ 
    Py_SetProgramName(argv[0]); 
    Py_Initialize(); 
    initspam(); 
} 

setupy.py内容:中src/test.h

from setuptools import setup,Extension 

spam_module = Extension('spam', 
     sources = ['spammodule.c'], 
     include_dirs=['src/'],) 

setup (name = 'Spam', 
    version = '1.0', 
    description = 'Sample module.', 
    ext_modules = [ spam_module ]) 

内容:

void maketest(void); 

src/test.c内容:

#include "test.h" 

void maketest() { 
    printf("test passed"); 
} 

我编译一切与python setup.py build,运行Python提示符我试图导入我的模块,并且得到错误后:

Python 2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import spam 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: ./spam.so: undefined symbol: maketest 

是否有人有线索怎么回事?

+1

你绝对无法将src/test.c的目标文件链接到'.so'中。将'src/test.c'添加到源列表中。 –

+0

你说得对,我认为包括'src/*'文件已经足够了,但是没有,正如你所说的其他文件应该列在源元组中,谢谢。我在我的帖子后添加了答案 – user3459276

+0

不,你应该*发布*你的答案作为*答案*。然后*接受它*! –

回答

0

确定球员感谢Antii为线索,你说的问题是test.c的应包含在源元组 所以我修改setup.py,一切工作正常 现在look`s这样的:

from setuptools import setup,Extension 

spam_module = Extension('spam', 
     sources = ['spammodule.c','src/test.c'], 
     include_dirs=['src/']) 

setup (name = 'Spam', 
    version = '1.0', 
    description = 'Sample module.', 
    ext_modules = [ spam_module ])