Модуль Python C - ImportError: Символ не найден: _Py_InitModule4_64 - PullRequest
0 голосов
/ 24 октября 2018

Я начинаю процесс написания модуля Python 3 на C. Написанный CI уже отлично компилируется (код, который я скомпилировал внизу поста).Я компилирую с:

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 показывает, что _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'])])

1 Ответ

0 голосов
/ 24 октября 2018

Вы написали свой модуль против Python 2 C API ( различные Py_InitModule функции предназначены исключительно для Python 2), но вы пытаетесь скомпилировать его и запустить с помощью Python 3. Cслой для CPython изменил лот между Python 2 и 3, и, насколько мне известно, нет инструмента 2to3 для кода C.

Вам необходимо написать код, совместимый с Python 3 API,работа на Python 3;самый простой (и единственный поддерживаемый подход поддерживается в версии 3.0-3.4) перевод однофазная инициализация PyModule_Create), но многофазная инициализация получает поведение, более похожее на модули, определенные вPython (например, можно полностью выгрузить их так, как это невозможно с однофазными модулями).Также изменилась структура имени точки входа, с initMODULENAME до PyInit_MODULENAME, поэтому вам также необходимо обновить его.

Я настоятельно рекомендую прочитать расширение Python 3модуль учебник .

...