我试图在我的python代码中使用一些C ++方法,而且我正在使用ctypes
库。我使用没有参数的简单main
和另一个名为printArgs
的简单方法编写了一个简单的C ++代码,该方法采用类型为char *
的参数。我还写了一个简单的python代码来导入这两个方法。我使用此命令创建了两个链接库(一个.so
和一个.a
因为我使用Debian):
g++ -o hello.so -shared -fPIC hello.cpp
然后使用export LD_LIBRARY_PATH=/the/path/to/the/linked/libraries/directory
。
获取main
方法没有问题,当我尝试printArgs
获得AttributeError
时。这是C ++代码:
#include <iostream>
using namespace std;
int printArgs(char * args_array){
for (int i = 0; i < 5; i++){
cout<<i<<"- "<<args_array[i]<<"\n";
}
return 0;
}
int main(){
cout<<"Hello\n";
return 0;
}
这是Python代码:
from ctypes import *
helloInCPP_lib = cdll.LoadLibrary("hello.a")
print helloInCPP_lib
helloInCPPMain = helloInCPP_lib.main
print helloInCPPMain
helloInCPPPrint = helloInCPP_lib.printArgs
print helloInCPPPrint
我得到了这个输出:
<CDLL 'hello.a', handle 9c45488 at b73d1e6c>
<_FuncPtr object at 0xb73e67e4>
Traceback (most recent call last):
File "testHelloInCPP.py", line 9, in <module>
helloInCPPPrint = helloInCPP_lib.printArgs(None)
File "/usr/lib/python2.6/ctypes/__init__.py", line 366, in __getattr__
func = self.__getitem__(name)
File "/usr/lib/python2.6/ctypes/__init__.py", line 371, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /etc/linked_libraries/hello.a: undefined symbol: printArgs
我还尝试了cdll.LoadLibrary("hello.so")
和/或helloInCPPPrint = helloInCPP_lib.printArgs(None)
;在两种情况下都得到了同样的错误。有什么想法吗?
我在VMWare Workstation和Python 2.6上使用Debian 32位。
答案 0 :(得分:3)
使用extern "C"
声明printArgs
:
#include <iostream>
using namespace std;
extern "C" {
int printArgs(char * args_array);
}
int printArgs(char * args_array){
for (int i = 0; i < 5; i++){
cout<<i<<"- "<<args_array[i]<<"\n";
}
}
int main(){
cout<<"Hello\n";
}
BTW,你应该传递一个字符串(c_char_p),而不是None
:
...
helloInCPPPrint = helloInCPP_lib.printArgs
helloInCPPPrint.argtypes = [c_char_p]
print helloInCPPPrint("ABCDE")
关于argtypes
,请参阅Specifying the required argument types (function prototypes)。
答案 1 :(得分:0)
我厌倦了使用@falsetru 编译解决方案
g++ -O3 -shared -std=c++11 -fPIC code.cpp -o lib.so
但是根据他们的回答 extern "C" 中提供的链接,不能没有对 code.c 的这个小修改:
#include <iostream>
using namespace std;
extern "C" int printArgs(char * args_array){
for (int i = 0; i < 5; i++){
cout<<i<<"- "<<args_array[i]<<"\n";
}
}