我有cython模块base.pyx和derived.pyx。 base.pyx
及其导入定义base.pxd
文件已定义,并使用derived.pyx
在cimport
文件中使用。这些文件放置在here。
在Python应用程序中使用cython生成的共享对象时,模块已正确导入,但在Cpp应用程序中使用库时,始终会出现ImportError: No module named 'base'
错误。
我还在我的Cpp应用程序中添加了当前路径
PyObject* path = PySys_GetObject("path");
PyObject* result = PyObject_CallMethod(path,"append","(s)",".");
Py_XDECREF(result);
即使这样,应用程序也看不到cython模块。请让我知道这种路径不匹配的原因是什么。
答案 0 :(得分:5)
此处的一些混淆是关于cimport
的行为 - OP试图使用derived.pyx
编辑cimport
的文件base.pyx
,并试图通过C ++。
cimport
做了两件事:
cdef
或.pyx
文件中定义的.pxd
函数,以便它可以访问这些函数。这发生在编译时。 import
那个模块。这在运行时发生,可以通过检查生成的C代码来查看。 import
是" import
蚂蚁"有两个原因:
base.pyx
中使用的函数可能需要在base中初始化全局变量或类,这在导入时完成。
它会导致base
共享对象物理加载到内存中,并将derived
中的某些函数指针初始化为cdef
中的base
函数
请注意,import
并未真正将base
添加到derived
的模块字典中,因此它并不完全相同一个Python导入。
我认为OP的一部分令人困惑的是import
。
第二个问题仅在提问时显示,因为它涉及一个未写在问题中的关键细节。我设法让代码按照提供的方式工作:
python3 setup.py build_ext --inplace
g++ test.cpp -o test `python3-config --libs --includes` ./derived.cpython-36m-x86_64-linux-gnu.so
./test
(其中第二行可能需要更改以匹配已编译的派生模块的确切名称)。 @PierredeBuyl做了一些稍微不同的事情,但同样发现代码没有任何变化。
问题实际上是OP正在将derived.cpython-36m-x86_64-linux-gnu.so
和base.cpython-36m-x86_64-linux-gnu.so
重命名为libderived.so
和libbase.so
。对于与derived
程序直接关联的test
,这并不是一个问题,但这意味着Python导入机制无法找到base
(因为它已重命名)。
作为社区维基发布,让自己与尽可能多的声誉脱离关系,因为我认为这是一个共同努力的事情,并且有一些令人不满意的解决方案。