自定义Python扩展 - 导入错误:未定义的符号

时间:2017-12-04 00:22:30

标签: python c python-3.x

学习如何在Python中编写C扩展。执行ptest.py

时遇到以下错误
Traceback (most recent call last):
  File "ptest.py", line 1, in <module>
    import euler_py as eul
ImportError: /usr/local/lib/python3.6/site-packages/euler_py.cpython-
36m-x86_64-linux-gnu.so: undefined symbol: problem_one

我假设这是某种类型的链接问题。

setup.py

sources = glob.glob('ext/*.c')

euler = Extension(
    'euler_py',
    include_dirs=['src'],
    sources=sources,
    extra_compile_args=['-std=c99']
)

setup(
    name='euler_py',
    version='0.1',
    description='Project Euler Solutions',
    ext_modules=[euler]
)

ptest.py

import euler_py as eul

print(eul.problem_one(10))

基础函数位于/src,我写了test.c以纯粹在C中进行测试。我的扩展位于/ext/euler_py.c下方,如下所示

转/ euler_py.c

#include <Python.h>
#include "../src/euler.h"

static char module_docstring[] = "Provides interface to Project Euler problems";

/*
 * Function implementations
 */


static PyObject* euler_py_problem_one(PyObject *self, PyObject *args)
{
    int max, result;

    if (!PyArg_ParseTuple(args, "i", &max))
        return NULL;

    result = problem_one(max);

    return Py_BuildValue("i", result);
}
// END function implementations

// Wire in functions to module
static PyMethodDef module_methods[] = {
        {"problem_one", euler_py_problem_one, METH_VARARGS, "Solution to problem 1"},
        {NULL, NULL, 0, NULL}
};


// Module definition
static struct PyModuleDef euler_py_module = {
        PyModuleDef_HEAD_INIT,
        "euler_py",
        module_docstring,
        -1,
        module_methods
};

// Module initialization function
PyMODINIT_FUNC PyInit_euler_py(void)
{
    return PyModule_Create(&euler_py_module);
}

回购是here。我和library_dirs&amp; include_dirs启动Extension(),没有运气。 Python版本3.6。需要再看看。

修改

回购链接自原始询问后发生了变化。添加了与之前相同的庄园中其他3个功能的链接。

1 个答案:

答案 0 :(得分:3)

您忘记包含所有源文件:

sources = glob.glob('ext/*.c') + glob.glob('src/*.c')

您可以使用setup.py build -fv看到c扩展程序构建详细信息:

$ python setup.py build -fv
...
clang -bundle -undefined dynamic_lookup build/temp.macosx-10.13-x86_64-3.6/ext/euler_py.o build/temp.macosx-10.13-x86_64-3.6/src/euler.o build/temp.macosx-10.13-x86_64-3.6/src/helpers.o -o build/lib.macosx-10.13-x86_64-3.6/euler_py.cpython-36m-darwin.so

现在helpers.oeuler.o已正确关联。