python - 从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 函数。
解决方案
如果您在 so 文件上使用 readelf -Ws,它将在 so 库中为您提供项目:
FUNC 全局默认值 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 知道您实际上是在传递字符串。这可能是可行的,但不像上面那么容易。
推荐阅读
- android - 向 Firebase 中的所有用户推送通知
- python - 为什么这个 ML 模型的准确率为零?
- javascript - 为什么我的 React 无法读取内部 api (flask) 数据?
- c++ - 生成随机二进制数序列的问题
- airflow - 基于操作员类型的气流并行度
- python - 为什么播放器类中的自变量不更新
- python-3.x - 在 if 语句中检查范围的问题
- reactjs - 如何将道具从子组件传递给父组件
- scikit-learn - 如何限制 sklearn 中岭回归模型使用的处理器数量?
- linux - git --pretty 选项中的 Trailers 选项