';进口恐怖主义';在Python扩展模块包装C库中
(更新3包含我希望获得答案的问题。更新2指我试图理解和解决此问题所做的更正) 我试图让Python扩展模块包装一个C库(在本例中,这只是书(3er版)中描述的一个示例)。问题是我遇到了经典错误';进口恐怖主义';在Python扩展模块包装C库中,python,c,compilation,cython,Python,C,Compilation,Cython,(更新3包含我希望获得答案的问题。更新2指我试图理解和解决此问题所做的更正) 我试图让Python扩展模块包装一个C库(在本例中,这只是书(3er版)中描述的一个示例)。问题是我遇到了经典错误 ImportError: dynamic module does not define init function (initsample) 当我尝试导入模块时 这本书本身有如下评论: 对于下面的所有配方,假设前面的代码位于名为 sample.c中的定义可以在名为sample.h的文件中找到,并且已经
ImportError: dynamic module does not define init function (initsample)
当我尝试导入模块时
这本书本身有如下评论:
对于下面的所有配方,假设前面的代码位于名为
sample.c中的定义可以在名为sample.h的文件中找到,并且已经
堆积到一个库libsample中,该库可以链接到其他C代码
编译和链接因系统而异,但这不是主要关注点。
假设您使用的是C代码,那么您已经明白了这一点
我想我弄错了。这就是我正在做的:首先,我有以下文件:
➜ Sample ls
csample.pxd sample.c sample.h sample.pyx setup.py
文件的内容与包含书中描述的文件一致。假设所有内容都被正确复制。然后我编译sample.c
➜ Sample gcc -c -fPIC -I/path/to/python2.7 sample.c
这将创建sample.o
,我将继续创建一个共享库:
➜ Sample gcc -shared sample.o -o libsample.so
它创建一个libsample.so
,最后运行setup.py
文件:
➜ Sample python setup.py build_ext --inplace
running build_ext
skipping 'sample.c' Cython extension (up-to-date)
building 'sample' extension
creating build
creating build/temp.linux-x86_64-2.7
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/path/to/include/python2.7 -c sample.c -o build/temp.linux-x86_64-2.7/sample.o
gcc -pthread -shared build/temp.linux-x86_64-2.7/sample.o -L. -L/path/to/lib -lsample -lpython2.7 -o /path/to/sample.so
然而,我得到了同样的错误。我遗漏了什么
这是我的setup.py
(最终,我复制了一个部件以清理以前的构建):
更新2
我想知道跑步后的感觉是否正常
python setup.py build_ext --inplace
文件sample.c
将替换为cythonized版本。
我假设运行setup.py
时使用的是cython sample.c
,但我这样问是因为昨天我错误地编译了cython化版本sample.c
(在删除libsample.so
,sample.o
,sample.so
,这些都是在前一次运行中创建的)在更新了sample.pyx
之后,我得到了以下错误:
>>> import sample
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./sample.so: undefined symbol: divide
错误。然后我像往常一样继续:
➜ Sample gcc -c -fPIC -I/path/to/python2.7 sample.c
➜ Sample gcc -shared sample.o -o libsample.so
➜ Sample python setup.py build_ext --inplace
running build_ext
cythoning sample.pyx to sample.c
warning: sample.pyx:27:42: Use boundscheck(False) for faster access
building 'sample' extension
creating build
creating build/temp.linux-x86_64-2.7
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/path/to/include/python2.7 -c sample.c -o build/temp.linux-x86_64-2.7/sample.o
gcc -pthread -shared build/temp.linux-x86_64-2.7/sample.o -L. -L/path/to/lib -lsample -lpython2.7 -o /path/to/Sample/sample.so
➜ Sample python
>>> import sample
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: libsample.so: cannot open shared object file: No such file or directory
这意味着我需要在环境变量LD_LIBRARY_PATH中设置当前目录。但是,我使用了一种粗糙的方法:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/Sample
正确的方法是什么?可能使用setup.py
中的一些参数?关于我发现的几个问题,我想得到一个关于为什么会发生所有这些的答案:
sample.c
在运行python setup.py build\u ext--inplace
时被替换,这样可以吗sample.c
sample.pyx
以获得正确的输出(而不是跳过'sample.c'Cython扩展名(最新)
,以获得错误的输出)导入错误的正确方法是什么:libsample.so:无法打开共享对象文件:没有这样的文件或目录
setup.py
中是4.的一个可能选项:
runtime_library_dirs=['./'],
但是,这需要
libsample.so
与setup.py
位于同一目录中。请向我们显示您的setup.py
文件。此外,请验证Cython是否可以在您的sample.pyx
文件上工作(使用Cython sample.pyx
)@Kevin谢谢。cython sample.pyx
可以工作,但它替换了同一目录中的文件sample.c。我将用setup.py
和?Dos更新我的问题。您的模块确实包含提到的函数initsample()
?如果没有,请再次阅读错误消息(“importorror:dynamic module没有定义init函数(initsample)
”。@RobertSmith所以您有理由:不管您是否知道,Python模块系统要求每个模块中都有这个函数:aPyMODINIT\u FUNC initNAME(void)
,其中NAME
是您模块的名称。如果此函数不存在,则会出现此错误。在正确的名称下执行正确的模块初始化,则错误消失。@gl:Cython负责提供此函数;这不是OP的错误。
ImportError: libsample.so: cannot open shared object file: No such file or directory
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/Sample
runtime_library_dirs=['./'],