ctypes如何将字符串从python传递给c ++函数,以及如何将字符串从c ++传递给python [英] ctypes how to pass string from python to c++ function, and how to return string from c++ function to python
问题描述
我想从python调用c ++函数,此c ++函数将char *作为参数,并返回字符串.下面是我的代码.
I want to call a c++ function from python, this c++ function takes char* as parameter, and return string. Below is my code.
wrapper.cpp
wrapper.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
compile wrapper.cpp to example.so
g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.7/
wrapper.py
wrapper.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"
函数.
This has nothing to do with ctypes; your C++ code is invalid in itself. You can't define an extern "C"
function that returns a string
.
在使用相同库的C ++程序的快速测试中,它还会打印垃圾.
In a quick test with a C++ program that uses the same library, it also prints garbage.
我还编写了一个C程序,该程序定义了一个名为 string
的东西,其布局与 std :: string
相同,只是我可以对其进行编译并查看会发生什么.它还会打印垃圾,然后在〜string
中进行段错误.
I also wrote a C program that defines something called string
with the same layout as std::string
just so I could compile it and see what happens; it also prints garbage, and then it segfaults in ~string
.
因此,Python程序还会打印垃圾也就不足为奇了.
So, it's not surprising that the Python program also prints garbage.
稍作更改,一切正常:
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".)
(Or, from the C++ version, the same thing but with "Tom" in the last line.)
当然,出于显而易见的原因,这并不是一个很好的解决方案,但它表明返回 string
是问题所在.
Of course for obvious reasons this isn't a very good solution, but it shows that returning string
is the problem.
当我尝试编译您的C ++代码时,g ++-4.5和clang-apple-4.0都向我发出了有关此问题的警告(尽管g ++-apple-4.2并未这样做,除非我添加了额外的-W标志).当编译器向您发出警告时,通常就是即使编译后我的代码为什么也会做错事"的答案.
Both g++-4.5 and clang-apple-4.0 warned me about exactly this problem when I tried to compile your C++ code (although g++-apple-4.2 didn't, unless I added an extra -W flag). When the compiler gives you a warning, that's often the answer to "why does my code do the wrong thing even though it compiles".
您的代码还有其他错误:
A few other things wrong with your code:
- 您不会在.cpp文件中使用任何来自Python的内容.通常,使用
ctypes
的全部目的是使您的C或C ++代码不必了解Python.是您的Python代码知道这一点.因此,请勿包含或链接. - 如果您不打算修改非常量
char *
,通常是个坏主意.我的C ++驱动程序必须使用const_cast< char *>(name.c_str())
而不是name.c_str()
来调用它.另外,这可以防止编译器注意到您正在执行的其他操作.
- You don't make any use of anything from Python in your .cpp file. And in general, the whole point of using
ctypes
is so your C or C++ code doesn't have to know anything about Python; it's your Python code that knows about it. So, don't include or link. - It's generally a bad idea to take a non-const
char*
if you aren't planning to modify it. My C++ driver had to call it withconst_cast<char*>(name.c_str())
instead of justname.c_str()
. Also, this can prevent the compiler from noticing other things that you're doing.
这是我上面提到的C ++驱动程序:
Here's the C++ driver I mentioned above:
#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
调用的内联位置,但实际上,细节并不重要;它可以直接插入行中.该代码不应该起作用,也不起作用,那么谁在乎为什么呢?
Also, if I play around with different optimization settings or reorganize the code a bit, in my C++ driver, sometimes your code actually works, sometimes it prints garbage, and sometimes it segfaults. My first guess would be that it depends where the ~string
call gets inlined—but really, the details don't matter; the code shouldn't work, and it doesn't, so who cares why?
这篇关于ctypes如何将字符串从python传递给c ++函数,以及如何将字符串从c ++传递给python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!