我正在开始用C语言编写Python 3模块的过程。我编写的C语言已经可以很好地编译(我在文章底部编译的代码)。我编译:
python3 setup.py build_ext --inplace
已构建的.so文件位于当前目录中。启动python3之后,当我导入模块时,出现此错误(用于截断路径的三点):
>>> import helloWorld
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(..., 2): Symbol not found: _Py_InitModule4_64
Referenced from: .../helloWorld.cpython-36m-darwin.so
Expected in: flat namespace
in .../helloWorld.cpython-36m-darwin.so
如何实现符号 _Py_InitModule4_64 ?
如果这意味着一切,我正在运行macOS High Sierra
在 helloWorld.cpython-36m-darwin.so 中运行 nm 显示_Py_InitModule4_64未定义,那么这是否证明在编译过程中存在问题?
nm helloWorld.cpython-36m-darwin.so
U _Py_BuildValue
U _Py_InitModule4_64
0000000000000eb0 t _helloWorld
0000000000001060 d _helloWorld_docs
0000000000001020 d _helloworld_funcs
0000000000000e80 T _inithelloWorld
U dyld_stub_binder
test.c:
#include <Python/Python.h>
static PyObject* helloWorld(PyObject* self) {
return Py_BuildValue("s", "Hello, Python extensions!!");
}
static char helloWorld_docs[] =
"helloWorld( ): Any message you want to put here!!\n";
static PyMethodDef helloworld_funcs[] = {
{"helloWorld", (PyCFunction)helloWorld,
METH_NOARGS, helloWorld_docs},
{NULL}
};
void inithelloWorld(void) {
Py_InitModule3("helloworld", helloworld_funcs, "Extension module example!");
}
setup.py:
from distutils.core import setup, Extension
setup(name = 'helloWorld', version = '1.0', \
ext_modules = [Extension('helloWorld', ['test.c'])])
答案 0 :(得分:3)
您是根据Python 2 C API(the various Py_InitModule
functions仅用于Python 2)编写模块的,但是您试图对其进行编译并与Python 3一起运行。CPython的C层更改了在Python 2和3之间切换,据我所知,没有2to3
工具用于C代码。
您需要编写与Python 3 API兼容的代码才能在Python 3上工作;最简单(也是3.0-3.4支持的唯一方法)的翻译是single-phase initialization(使用PyModule_Create
),但是multi-phase initialization的行为更类似于Python中定义的模块(例如,可以完全卸载它们以单相模块无法实现的方式)。入口点名称的结构也从initMODULENAME
更改为PyInit_MODULENAME
,因此您也需要对其进行更新。