在 python 中使用链接库中的方法时出现属性错误

Attribute error while using methods from linked libraries in python

本文关键字:属性 错误 方法 python 链接      更新时间:2023-10-16

我正在尝试在我的python代码中使用一些C++方法,并且正在使用ctypes库。我编写了一个简单的C++代码,使用一个没有参数的简单main和另一个名为 printArgs 的简单方法,该方法采用 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<<"Hellon";
    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工作站和Python 2.6上使用Debian 32位。

使用 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<<"Hellon";
}

顺便说一句,你应该传递一个字符串(c_char_p),而不是None

...
helloInCPPPrint = helloInCPP_lib.printArgs
helloInCPPPrint.argtypes = [c_char_p]
print helloInCPPPrint("ABCDE")

关于argtypes ,请参阅指定所需的参数类型(函数原型)。

我厌倦了通过使用@falsetru编译解决方案

g++ -O3 -shared -std=c++11 -fPIC code.cpp -o lib.so

但是不能没有对code.c进行这种小的修改,根据他们的答案Extern"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";
    }
}
相关文章: