英文:
Python Import Error: Undefined Symbol for Custom C Module
问题
I've translated the content as requested:
我一直在Python中尝试使用C模块,编译没有问题。但是,在导入模块时,我收到以下错误消息:
>>> import _strrev
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /path/to/my/module.so: undefined symbol: strrev
文件的内容如下:
_strrev.c
#include <Python.h>
#include <string.h>
static PyObject* _strrev(PyObject* self, PyObject *args) {
PyObject* name;
if (!PyArg_ParseTuple(args, "U", &name)) {
return NULL;
}
PyObject *ret = strrev(*name);
return ret;
}
static struct PyMethodDef methods[] = {
{"strrev", (PyCFunction)_strrev, METH_VARARGS},
{NULL, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"_strrev",
NULL,
-1,
methods
};
PyMODINIT_FUNC PyInit__strrev(void) {
return PyModule_Create(&module);
}
setup.py
from distutils.core import setup, Extension
setup(
name='strrev_lib',
version='1',
ext_modules=[Extension('_strrev', ['_strrev.c'])],
)
运行这个对象文件上的nm -D
命令时,我得到以下输出:
$ nm -D _strrev.cpython-39-x86_64-linux-gnu.so
w __cxa_finalize@GLIBC_2.2.5
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U PyArg_ParseTuple
00000000000011a0 T PyInit__strrev
U PyModule_Create2
U __stack_chk_fail@GLIBC_2.4
U strrev
我可以看到strrev在这里,所以我不明白为什么它说该符号未定义。
我还尝试使用不同的模块,当尝试导入它时,它完全正常运行。
$ python3
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits", or "license" for more information.
>>> import _hello
>>> _hello.hello("Jared")
'hello Jared'
文件的内容如下:
_hello.c
#include <Python.h>
static PyObject* _hello(PyObject* self, PyObject *args) {
PyObject* name;
if (!PyArg_ParseTuple(args, "U", &name)) {
return NULL;
}
PyObject *ret = PyUnicode_FromFormat("hello %U", name);
return ret;
}
static struct PyMethodDef methods[] = {
{"hello", (PyCFunction)_hello, METH_VARARGS},
{NULL, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"_hello",
NULL,
-1,
methods
};
PyMODINIT_FUNC PyInit__hello(void) {
return PyModule_Create(&module);
}
setup.py
from setuptools import setup
from setuptools import Extension
setup(
name='hello-lib',
version='1',
ext_modules=[Extension('_hello', ['_hello.c'])],
)
有人能否给我一些建议,我做错了什么?是编译还是我编写的代码有问题?任何帮助将不胜感激!
英文:
I've been experimenting with C modules in python and I've had no problems with compilation. However, when it comes to importing the module I receive this error message:
>>> import _strrev
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /path/to/my/module.so: undefined symbol: strrev
The contents of the file are
_strrev.c
#include <Python.h>
#include <string.h>
static PyObject* _strrev(PyObject* self, PyObject *args) {
PyObject* name;
if (!PyArg_ParseTuple(args, "U", &name)) {
return NULL;
}
PyObject *ret = strrev(*name);
return ret;
}
static struct PyMethodDef methods[] = {
{"strrev", (PyCFunction)_strrev, METH_VARARGS},
{NULL, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"_strrev",
NULL,
-1,
methods
};
PyMODINIT_FUNC PyInit__strrev(void) {
return PyModule_Create(&module);
}
setup.py
from distutils.core import setup, Extension
setup(
name='strrev_lib',
version='1',
ext_modules=[Extension('_strrev', ['_strrev.c'])],
)
When running nm -D on this object file, I get this output
$ nm -D _strrev.cpython-39-x86_64-linux-gnu.so
w __cxa_finalize@GLIBC_2.2.5
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U PyArg_ParseTuple
00000000000011a0 T PyInit__strrev
U PyModule_Create2
U __stack_chk_fail@GLIBC_2.4
U strrev
I can see that strrev is here, so I don't understand why it says that the symbol in undefined.
I've also tried using a different module and that works perfectly fine when attempting to import it.
$ python3
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _hello
>>> _hello.hello("Jared")
'hello Jared'
The contents of the files are:
_hello.c
#include <Python.h>
static PyObject* _hello(PyObject* self, PyObject *args) {
PyObject* name;
if (!PyArg_ParseTuple(args, "U", &name)) {
return NULL;
}
PyObject *ret = PyUnicode_FromFormat("hello %U", name);
return ret;
}
static struct PyMethodDef methods[] = {
{"hello", (PyCFunction)_hello, METH_VARARGS},
{NULL, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"_hello",
NULL,
-1,
methods
};
PyMODINIT_FUNC PyInit__hello(void) {
return PyModule_Create(&module);
}
setup.py
from setuptools import setup
from setuptools import Extension
setup(
name='hello-lib',
version='1',
ext_modules=[Extension('_hello', ['_hello.c'])],
)
Can anyone give me pointers as to what I'm doing wrong? Is it something with the compilation or with the code that I've written? Any help would be appreciated!
答案1
得分: 1
> 我可以看到 strrev
在这里,所以我不明白为什么它说这个符号未定义。
恰恰相反:您可以看到strrev
不在 那里 - nm
输出中的 U
表示_未定义_。
strrev
似乎是一个Windows的东西,而您不在Windows上。在GLIBC中没有这样的符号:
$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep strrev
$
要解决这个问题,您需要自己实现strrev()
。
英文:
> I can see that strrev is here, so I don't understand why it says that the symbol in undefined.
Au contraire: you can see that strrev
is not there -- U
in nm
output means undefined.
The strrev
appears to be a Windows thing, and you are not on Windows. There is no such symbol in GLIBC:
$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep strrev
$
To fix this, you would need to implement strrev()
yourself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论