gpt4 book ai didi

Python 无法导入 (cython) 共享库

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:21:10 51 4
gpt4 key购买 nike

最近几天,我设法将 rnnlib 编译为共享库。它是一个 C++ 库。我想从 python 调用它。我的选择落到了cython。所以我创建了一个 C++ 函数void libCall(int argc, char* argv[]) 这实际上与 rnnlib 的主要功能相同,但已重命名以使其更易于调用。 rnnlib 库是/usr/lib

我的 rnn.pyx 看起来像那样

# distutils: language = c++

cdef extern from "libcall.hpp":
void libCall(int argc, char* argv[])

cpdef call():
print 'hallo welt'

我的setuprnn.py

from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import os

os.environ["CC"] = "gcc"
os.environ["CXX"] = "g++"
os.environ["CFLAGS"]="-I./src/"

setup(ext_modules = cythonize(
"rnn.pyx", # our Cython source
libraries=["rnnlib","netcdf_c++","netcdf","m","stdc++"], # additional source file(s)
language="c++", # generate C++ code
))

我已经创建了一个额外的测试文件来查看是否可以调用该库。测试.cpp

#include <iostream>
#include "libcall.hpp"

using namespace std;


int main(int argc, char* argv[])
{
libCall(argc, argv);
}

现在当我构建 test.cpp 时

g++ -Wall -I./src/ test.cpp -lrnnlib -lnetcdf_c++ -lnetcdf -lm -lstdc++ -o test

我可以运行它并且一切正常。当我运行 python setuprnn.py build_ext -i 时,我得到了 rnn.so 和 rnn.cpp,这很好。但是当我运行 python 并输入 import rnn

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./rnn.so: undefined symbol: _ZNK5NcVar3getEPcPKl

我用 nm 查看了 rnn.so 并得到了这个:

000000000003f140 W _ZNK5Mdrnn5printERSo
U _ZNK5NcDim4sizeEv
U _ZNK5NcVar3getEPcPKl

所以我假设常量存在于库中?

我想不通为什么。我发现了一个类似的线程 Python ImportError - undefined symbol - for custom C++ module但不知道如何在这里应用它:

python setuprnn.py build_ext -i
Compiling rnn.pyx because it changed.
Cythonizing rnn.pyx
running build_ext
building 'rnn' extension
gcc -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -I./src/ -fPIC -I/usr/include/python2.7 -c rnn.cpp -o build/temp.linux-x86_64-2.7/rnn.o
......

g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -I./src/ build/temp.linux-x86_64-2.7/rnn.o -o /media/psf/dfki/test/rnn.so

当我搜索它时。我只找到这个网站http://upstream.rosalinux.ru/compat_reports/netcdf/3.4_to_3.5.0/abi_compat_report.html

所以我想到了一个向后兼容的问题,这就是我安装 netcdf 库 4.1.3 的原因,因为它是完全向后兼容的

我希望有人能帮助我,因为这真的很令人沮丧。

最佳答案

我无法重现您的问题。这是我创建的用于创建文件、构建扩展并在 python 中运行代码的脚本:

#!/bin/sh -e

echo "Cleaning up /tmp"
rm -f /tmp/rnn.pyx /tmp/rnn.so /tmp/setuprnn.py /tmp/libcall.hpp /tmp/rnn.cpp /tmp/rnn.so
rm -rf /tmp/build/

echo "Creating /tmp/rnn.pyx"
cat > /tmp/rnn.pyx << EOF
# distutils: language = c++

cdef extern from "libcall.hpp":
void libCall(int argc, char* argv[])

cpdef call():
print 'hallo welt'
EOF

echo "Creating /tmp/setuprnn.py"
cat > /tmp/setuprnn.py << EOF
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import os

os.environ["CC"] = "gcc"
os.environ["CXX"] = "g++"
os.environ["CFLAGS"]="-I./src/"

setup(ext_modules = cythonize(
"rnn.pyx", # our Cython source
libraries=["rnnlib","netcdf_c++","netcdf","m","stdc++"], # additional source file(s)
language="c++", # generate C++ code
))
EOF

echo "Creating /tmp/libcall.hpp"
touch /tmp/libcall.hpp

echo "Building rnn.so extension"
python setuprnn.py build_ext -i

python -c "import rnn; print('-' * 30); print('Imported rnn'); print(dir(rnn))"

这是我得到的结果:

Cleaning up /tmp
Creating /tmp/rnn.pyx
Creating /tmp/setuprnn.py
Creating /tmp/libcall.hpp
Building rnn.so extension
Compiling rnn.pyx because it changed.
Cythonizing rnn.pyx
running build_ext
building 'rnn' extension
creating build
creating build/temp.linux-x86_64-2.7
gcc -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -I./src/ -fPIC -I/usr/include/python2.7 -c rnn.cpp -o build/temp.linux-x86_64-2.7/rnn.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -I./src/ build/temp.linux-x86_64-2.7/rnn.o -o /tmp/rnn.so
------------------------------
Imported rnn
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__test__', 'call']

我觉得不错。当然,我没有正确实现你的所有代码,我写的任何东西都没有引入 netcdf 或你引用的其他库。也许您可以更新您的描述,以便其他人可以对此进行测试?

关于Python 无法导入 (cython) 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26120236/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com