我有一个c ++程序,我正在尝试包装/转换为Cython.它使用特定的库,由于某种原因,不会导致导入的工作模块.顺便说一句,有一个工作的c ++程序.这是setup.py:
ext_modules = [
Extension(
name="libnmfpy",
sources=["interface/nmf_lib.pyx"],
include_dirs = ["../src/", numpy.get_include()],
libraries=["nmf","mpi_cxx","mpi","m"],
library_dirs=["../build/Linux/bin.release","/usr/local/lib/","/usr/lib"],
language="c++",)
]
setup(
name = 'libnmfpy',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
)
Run Code Online (Sandbox Code Playgroud)
我应该提一下,它似乎是导致问题的libnmf.libnmf的第一个构建将导致此脚本生成此错误:
/usr/bin/ld: ../build/Linux/bin.release/libnmf.a(nmf.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
../build/Linux/bin.release/libnmf.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
当我用-fPIC重建libnmf时,setup会生成一个libnmfpy.so,但是当我在另一个脚本中导入它时,我会得到上面提到的未定义符号:
Traceback (most recent call last):
File "test.py", line 1, in <module>
import libnmfpy
ImportError: $path/cython/libnmfpy.so: undefined symbol: …Run Code Online (Sandbox Code Playgroud) 我收到了一些看起来像这样的代码:
在"header.hpp"中:
enum class my_enum_type {
val1 = 0;
...
}
Run Code Online (Sandbox Code Playgroud)
在"header_lib.pyx"中:
cdef extern from "header.hpp":
enum my_enum_type:
val1 = 0;
...
...
Run Code Online (Sandbox Code Playgroud)
稍后在"header_lib.pyx"中:
def foo():
...
return my_enum_type.val1
Run Code Online (Sandbox Code Playgroud)
我被告知这应该没有问题,但是从我刚才的经验来看并非如此,并且在这篇文章中很明显:在Cython代码中定义将在代码的C部分中使用的枚举.
但是,如果我写"return val1",它本身也不会识别"val1".这样做的正确方法是什么?