我有cython模块base.pyx和derived.pyx。base.pyx及其导入定义base.pxd文件被定义,并使用cimport在derived.pyx文件中使用。文件被放置为这里。
在我的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模块。请让我知道造成这种错配的原因是什么。
发布于 2017-05-11 10:54:43
这里的部分混淆是关于cimport - OP的行为,它试图使用cimport编辑base.pyx的文件derived.pyx,并试图从C++中做到这一点。
cimport做了两件事:
.pyx或.pxd文件中定义的.pyx函数,以便能够访问这些函数。这种情况发生在编译时。import就是这个模块。这发生在运行时,可以通过检查生成的C代码来查看。import是"important“,有两个原因:1. The functions used in `base.pyx` might need global variables or classes to be initialized in base, which is done at import time.
2. It causes the `base` shared object to be physically loaded into memory, and initializes some function pointers (in `derived`) to the `cdef` functions in `base`.请注意,import并不实际将base添加到derived的模块字典中,因此它与derived导入不太一样。
我认为,令人困惑的部分原因是这个稍微出乎意料的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 (因为它被重命名了)。
张贴作为社区维基,以使自己与尽可能多的声誉脱节,因为我认为这是一种共同努力与一个有点不满意的解决方案。
https://stackoverflow.com/questions/43764950
复制相似问题