我想从 python 调用一个 c++ 函数,这个 c++ 函数以 char* 作为参数,并返回字符串。下面是我的代码。
包装器.cpp
#include <Python.h>
#include <string>
#include <iostream>
using namespace std;
extern "C"
string return_string(char* name){
cout<<strlen(name)<<endl;
cout<<name<<endl;
string s = "hello ";
s += name;
return s;
}
将wrapper.cpp编译成example.so
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.7/
包装器.py
import os
from ctypes import *
lib = cdll.LoadLibrary('./example.so')
lib.return_string.restype = c_char_p
lib.return_string.argtypes = [c_char_p]
name = create_string_buffer("Tom")
s = lib.return_string(name);
print s
print name
这是我的输出
18
��H�L�l���A���
1
<ctypes.c_char_Array_4 object at 0x7f5f480be710>
如何让它发挥作用?
最佳答案
这与ctypes无关;你的 C++ 代码本身是无效的。你不能定义 extern "C"
返回 string
的函数.
在使用相同库的 C++ 程序的快速测试中,它也会打印垃圾。
我还写了一个 C 程序,它定义了一个叫做 string
的东西。布局与 std::string
相同这样我就可以编译它,看看会发生什么;它还打印垃圾,然后在 ~string
中出现段错误.
因此,Python 程序也打印垃圾也就不足为奇了。
稍作改动,一切正常:
extern "C"
const char *return_string(char* name){
cout<<strlen(name)<<endl;
cout<<name<<endl;
static string s = "hello ";
s += name;
return s.c_str();
}
我得到这个输出:
3
Tom
hello Tom
<ctypes.c_char_Array_4 object at 0x11011c7a0>
(或者,从 C++ 版本开始,同样的事情,但在最后一行带有“Tom”。)
当然,由于显而易见的原因,这不是一个很好的解决方案,但它表明返回 string
是问题所在。
当我试图编译你的 C++ 代码时,g++-4.5 和 clang-apple-4.0 都警告我这个问题(尽管 g++-apple-4.2 没有,除非我添加了一个额外的 -W 标志)。当编译器给你一个警告时,这通常是对“为什么我的代码在编译时做错事”的回答。
您的代码还有其他一些问题:
- 您没有在 .cpp 文件中使用任何来自 Python 的内容。总的来说,使用
ctypes
的全部意义这样您的 C 或 C++ 代码就不必了解 Python 的任何知识;知道它的是你的 Python 代码。因此,请勿包含或链接。 - 采用非常量
char*
通常不是一个好主意如果您不打算修改它。我的 C++ 驱动程序必须用const_cast<char*>(name.c_str())
调用它而不仅仅是name.c_str()
.此外,这可以防止编译器注意到您正在做的其他事情。
这是我上面提到的 C++ 驱动程序:
#include <iostream>
#include <string>
using namespace std;
extern "C" string return_string(char* name);
int main(int argc, char *argv[]) {
string name("Tom");
string s(return_string(const_cast<char *>(name.c_str())));
cout << s << "\n";
cout << name << "\n";
return 0;
}
此外,如果我使用不同的优化设置或稍微重新组织代码,在我的 C++ 驱动程序中,有时您的代码确实有效,有时它会打印垃圾,有时会出现段错误。我的第一个猜测是这取决于 ~string
在哪里调用被内联——但实际上,细节并不重要;代码不应该工作,现在也没有,所以谁在乎为什么?
关于c++ - ctypes如何将字符串从python传递给c++函数,以及如何将字符串从c++函数返回给python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12500069/