Python 3.x - 导入密码化 C++ 代码时未定义的符号
python 3.x - Undefined symbol when importing cythonized c++ code
我试图从python调用c ++代码,在这个最小(ish(示例中使用cython:
# setup.py
import numpy as np
import glob
from distutils.core import setup
from Cython.Distutils import build_ext
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = "pytest",
version = "0.0.1",
author = "Herbert",
#cmdclass = {'build_ext': build_ext},
py_modules = ['pytest'],
ext_modules = cythonize(
'_pytest.pyx',
language="c++",
sources=['testcpp.cpp'],
#extra_compile_args=['-fopenmp', '-O3', '-ffast-math'],
include_dirs = [np.get_include(), '.'],
#extra_link_args=['-fopenmp']
)
)
# pytest.py
from __future__ import division
import os
import time
import numpy as np
import scipy.sparse
from _pytest import pyprint
pyprint()
# _pytest.pyx
# distutils: language = c++
# distutils: sources = testcpp.cpp
cimport cython
cdef extern void testprint ()
@cython.boundscheck(False)
def pyprint():
testprint()
#include <iostream>
void testprint()
{
std::cout << "C++ at work.n";
}
然后我"编译"这些:
#removing possible left overs:
$ rm -rf build/ __pycache__/ _pytest.cpp
$ rm -rf ~/venv3/lib/python3.4/site-packages/{_pytest.cpython-34m.so,pytest*}
$ python3 setup.py clean
.../lib/python3.4/site-packages/Cython/Compiler/Main.py:514: UserWarning: got unknown compilation options, please remove: sources, include_dirs
warnings.warn(message)
Compiling _pytest.pyx because it changed.
Cythonizing _pytest.pyx
running clean
$ python3 setup.py install
.../lib/python3.4/site-packages/Cython/Compiler/Main.py:514: UserWarning: got unknown compilation options, please remove: sources, include_dirs
warnings.warn(message)
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.4
copying pytest.py -> build/lib.linux-x86_64-3.4
running build_ext
building '_pytest' extension
creating build/temp.linux-x86_64-3.4
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC -I.../include -I/usr/include/python3.4m -c _pytest.cpp -o build/temp.linux-x86_64-3.4/_pytest.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC -I.../include -I/usr/include/python3.4m -c testcpp.cpp -o build/temp.linux-x86_64-3.4/testcpp.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
### !!!! The next statement shows that the `testcpp.cpp` file should be compiled and linked into `_pytest.cpython-34m.so`:
x86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.4/_pytest.o build/temp.linux-x86_64-3.4/testcpp.o -o build/lib.linux-x86_64-3.4/_pytest.cpython-34m.so
running install_lib
copying build/lib.linux-x86_64-3.4/pytest.py -> .../lib/python3.4/site-packages
copying build/lib.linux-x86_64-3.4/_pytest.cpython-34m.so -> ..../lib/python3.4/site-packages
running install_egg_info
Writing ..../lib/python3.4/site-packages/pytest-0.0.1.egg-info
但是,当我运行它时(从我的主目录,而不是项目目录,以确保使用已安装的版本(,动态链接器找不到测试打印符号:
$ python3 -c 'import pytest;'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File ".../lib/python3.4/site-packages/pytest.py", line 6, in <module>
from _pytest import pyprint
ImportError: .../lib/python3.4/site-packages/_pytest.cpython-34m.so: undefined symbol: testprint
这。。。标记 Python 3 虚拟环境的位置。请注意,如果我检查 .so,则会找到测试打印符号:
$ nm .../lib/python3.4/site-packages/_pytest.cpython-34m.so | grep testprint
U testprint
0000000000001e60 T _Z9testprintv
为什么 python 3 找不到测试打印符号?
抛开
所有的挫败感,我找到了解决方案。因此,_pytext.pyx
被处理为 _pytest.cpp
,经过预处理(g++ 中的 -E 开关(,声明:
extern "C" void testprint(void);
这是这个cython声明的结果:
cdef extern void testprint ()
基本上它声明了一个C function
(符号testprint
(,而C++ function
(符号_Z9testprintv
(是在.so文件中定义的。因为 testprint
!= _Z9testprintv
我们得到了一个undefined symbol: testprint
那么我们如何解决这个问题呢?我对最好的解决方案一无所知,但这似乎有效:
cdef extern from "testcpp.h":
cdef void testprint ()
相关文章:
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 为什么我的C++代码无法编译,出现未定义的引用错误
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 我的代码中C++未定义的引用错误?
- 是 VS 代码 MinGW 与 Win32 中未定义的错误
- 如何修复初学者C++代码中发生的未定义行为
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- 使用 Android NDK 使用 clang++ 编译C++代码时对"_Unwind_Resume"的未定义引用
- 我可以在将项目编译为静态库(未定义的引用)时在代码中使用 QImage 吗?
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- 代码::具有 SFML 2,4 的块中未定义的引用
- 在 C++ 中调用时对内联程序集代码的未定义引用
- C++:为什么这段代码给我内存问题/未定义的行为?
- 在另一台计算机中运行 GTKMM 代码时未定义的符号
- 未定义的行为确实有助于现代编译器优化生成的代码
- 为什么当我尝试编译时,我的 c++ 代码不断返回对我的一个构造函数的"未定义的引用"?
- 使用 gcc 编译和使用 clang 编译代码时未定义的引用
- 使用向量(STL)时,未定义的行为,请说明理性背后的以下代码输出
- 当我在Xcode上访问矩阵(openCV垫子)的位置时,为什么我会得到未定义的行为(exc_bad_access(代码=
- 节俭生成的代码未定义的参考