ctypes如何将字符串从python传递到c++函数,以及如何将字符串从c++函数返回到python

2024-06-28 20:06:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从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>

如何让它起作用?


Tags: 函数nameimportstringreturnsoincludeexample
1条回答
网友
1楼 · 发布于 2024-06-28 20:06:32
<>这与cType无关,你的C++代码本身就是无效的。不能定义返回stringextern "C"函数。

在使用同一库的C++程序的快速测试中,它还打印垃圾。

我还编写了一个C程序,它使用与std::string相同的布局定义了一个名为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和CLAN-APPLE-4.0都警告了我这个问题(尽管G++-APPLE 4.2没有,除非我添加了额外的W标志)。当编译器给你一个警告时,这通常是“为什么我的代码即使编译也会做错误的事情”的答案。

你的代码还有一些问题:

  • 在.cpp文件中不使用任何来自Python的内容。一般来说,使用{{CD7}}的全部要点是,你的C或C++代码不需要知道关于Python的任何东西,而是你知道的Python代码。所以,不要包含或链接。
  • 如果您不打算修改非常量char*,那么通常采用非常量是一个坏主意。我的C++驱动程序必须用^ {CD9}}来调用它,而不是只调用^ {CD10}}。此外,这可以防止编译器注意到您正在做的其他事情。

这是上面提到的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调用的内联位置,但实际上,细节并不重要;代码不应该工作,也不应该工作,所以谁在乎为什么?

相关问题 更多 >