C Python Module -- ImportError: Symbol not found: _Py_InitModule4_64

C Python Module -- ImportError: Symbol not found: _Py_InitModule4_64

我正在开始用 C 编写 Python 3 模块。我编写的 C 已经可以很好地编译(我在 post 底部编译的代码)。我编译:

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 如果这意味着什么


运行 nm 对于 helloWorld.cpython-36m-darwin.so 显示 _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'])])

您针对 Python 2 C API 编写了您的模块(the various Py_InitModule functions 纯粹用于 Python 2),但您正在尝试编译它并且 运行 it with Python 3. CPython的C层在Python2和3之间改了一个lot,没有2to3 据我所知,用于 C 代码的工具。

您需要编写 Python 3 API 兼容代码才能在 Python 3 上工作;最简单的(也是 3.0-3.4 支持的唯一方法)翻译是 single-phase initialization (with PyModule_Create), but multi-phase initialization 获得更像 Python 中定义的模块的行为(例如,可以以一种不可能的方式完全卸载它们相模块)。入口点名称的结构也发生了变化,从 initMODULENAMEPyInit_MODULENAME,因此您也需要更新它。

我强烈建议阅读 the Python 3 extension module tutorial