从python调用C ++函数并获取返回值

时间:2020-07-13 08:22:10

标签: python c++

我正在尝试从python脚本调用C ++函数。这是我的示例C ++和Python代码。

strfunc.cpp

#include <iostream>
#include <string>

using namespace std;

string getString()
{
    string hostname = "test.stack.com";
    return hostname;
}

strfunc.py

import ctypes

print(ctypes.CDLL('./strfunc.so').getString())

我使用以下命令从C ++程序编译并生成了一个共享库:

g++ -fPIC strfunc.cpp -shared -o strfunc.so

当我尝试执行strfunc.py时,出现以下错误:

$ ./strfunc.py 
Traceback (most recent call last):
  File "./strfunc.py", line 5, in <module>
    print(ctypes.CDLL('./strfunc.so').getString())
  File "/usr/lib64/python3.7/ctypes/__init__.py", line 372, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib64/python3.7/ctypes/__init__.py", line 377, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: ./strfunc.so: undefined symbol: getString

请帮助我了解如何解决此问题。相同的东西也可以用于int函数。

1 个答案:

答案 0 :(得分:1)

如果在so文件中使用readelf -Ws,它将为您提供so库中的项目:

全局默认功能12 _Z9getStringB5cxx11v

您将看到您的函数实际上在那儿,它的名字只是乱七八糟的。 因此,在库上调用ctype的合适名称是_Z9getStringB5cxx11v()。

但是,仍然有一些错误的地方。 将您的方法标记为外部,以使编译器知道它具有外部链接:

extern string getString()

或者,如果要将其用作getString(),则可以将其标记为extern“ C”,这将禁用c ++ mangler

extern "C" string getString()

但是无论哪种情况,我都认为您会发现一些内存问题。我认为正确的方法是将c样式指针返回到字符数组,然后由内存自行管理,类似这样的方法应该起作用:

strfunc.cpp:

#include <iostream>
#include <string>

using namespace std;

char hostname[] = "test.stack.com";

extern "C" char * getString()
{

        return hostname;

}

strfunc.py:

#!/usr/bin/env python
from ctypes import *

test=cdll.LoadLibrary("./strfunc.so")
test.getString.restype=c_char_p
print(test.getString())

在使用字符串的情况下,我认为您需要弄清楚如何管理内存并正确返回类型,以便告知python您实际上正在传递字符串。这可能是可行的,但并不像上面那样简单。

相关问题