我在CMake中创建共享库的CMake设置类似于
SET (CMAKE_CXX_FLAGS "-fPIC")
SET (LIB_UTILS_SRC
Utils.cpp
)
ADD_LIBRARY (UTILS SHARED
${LIB_UTILS_SRC}
)
Source Utils.cpp
double addTwoNumber(double x, double y)
{
return x + y;
}
尝试使用像
这样的CType访问'addTwoNumber'功能时import os
import ctypes as c
libPath = '/home/AP/workspace/LearningCPP/lib/libUTILS.so'
libUTILS = c.cdll.LoadLibrary(libPath)
prototype = c.CFUNCTYPE(
c.c_double,
c.c_double,
c.c_double
)
addTwoNumber = prototype(('addTwoNumber', libUTILS))
res = addTwoNumber(c.c_double(2.3), c.c_double(3.5) )
我收到了一些消息。
AttributeError: /home/AP/workspace/LearningCPP/lib/libUTILS.so:
undefined symbol: addTwoNumber
我使用“nm --demangle libUTILS.so”命令检查了libUTILS.so,它清楚地显示了“addTwoNumber”符号。
为什么我仍然从python中收到“未定义的符号”消息? 我猜测必须要设置一些编译器标志,以便符号正确。任何建议将不胜感激!
答案 0 :(得分:15)
有趣的是,我经常使用numpy.ctypes
,因为我经常不得不处理大型数据集,并且从来没有遇到任何问题,但我想我知道这里发生了什么,这就是g ++编译器破坏了名称,我这样做了:
生成文件:
g++ -Wall -fPIC -O2 -c Utils.cpp
g++ -shared -Wl -o libUTILS.so Utils.o
Utils.cpp
extern "C" double addTwoNumber(double x, double y)
{
return x + y;
}
test.py
import os
import ctypes as c
libUTILS = c.cdll.LoadLibrary('libUTILS.so')
prototype = c.CFUNCTYPE(
c.c_double,
c.c_double,
c.c_double
)
addTwoNumber = prototype(('addTwoNumber', libUTILS))
res = addTwoNumber(c.c_double(2.3), c.c_double(3.5) )
print res
输出:
$ python test.py
5.8
注意extern
关键字确保编译器不会破坏名称,你必须在windows下做一些额外的东西,我确实发现http://wolfprojects.altervista.org/dllforpyinc.php这很有趣。
我希望这会有所帮助。
我的机器:
$ g ++ --version
i686-apple-darwin10-g ++ - 4.2.1(GCC)4.2.1(Apple Inc. build 5666)(第3点) 版权所有(C)2007 Free Software Foundation,Inc。 这是免费软件;查看复制条件的来源。没有 保证;甚至不适用于适销性或特定用途的适用性。$ uname -a
Darwin MacBookPro 10.8.0 Darwin内核版本10.8.0:Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1 / RELEASE_I386 i386