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

查看:118
本文介绍了ctypes如何将字符串从python传递给c ++函数,以及如何将字符串从c ++传递给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 ++代码本身无效.您无法定义返回 string 的 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 with const_cast<char*>(name.c_str()) instead of just name.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆