从python调用c++函数

Posted

技术标签:

【中文标题】从python调用c++函数【英文标题】:Calling c++ function from python 【发布时间】:2018-10-21 13:59:12 【问题描述】:

我正在尝试从我的 Python 代码中调用 C++ 函数,如果我传递一个布尔值或 int 它可以完美运行,但如果我发送一个字符串,它只会打印第一个字符。 我正在编译:

g++ -c -fPIC foo.cpp -Wextra -Wall -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
python3 fooWrapper.py

这是 C++ 和 Python 代码:

Python:

from ctypes import cdll
lib = cdll.LoadLibrary("./libfoo.so")
lib.Foo_bar("hello")

c++:

#include <iostream>
#include <string>
#include <unistd.h>

void bar(char* string)
    printf("%s", string);


extern "C" 
    void Foo_bar(char* aString)
        bar(aString);
    

我知道Boost 库,但我无法下载它,除了字符串之外,这种方式效果很好。 谢谢你的帮助

【问题讨论】:

告诉我,%i 是做什么的? 另外,当你本质上是在写 C 时,你为什么声称这是 C++? 刚刚更改为 %s ,是旧的整数尝试。 因为这只是代码的一小部分,这是一个测试,但我看到我必须将它声明为extern "C" 才能调用它,但我可以在bar函数 您应该考虑提交针对 Python 的文档错误。 [Python 3] Extending Python with C or C++ 在他们的手册中没有出现对待主题。 wchar_t 显示在一处但未解释。 wchar_t 和宽字符不解释。 【参考方案1】:

问题在于,字符串在 Python 3 中作为指向 wchar_t wide characters 的指针传递。而在小端系统中,您的字符串可以用二进制编码为

"h\0\0\0e\0\0\0l\0\0\0l\0\0\0o\0\0\0\0\0\0\0"

当使用%s 打印时,它将在第一个空终止符处停止。


对于 UTF-8 编码的字节字符串 (char *) you need a bytes object。例如:

lib.Foo_bar("hello".encode())

或使用字节文字:

lib.Foo_bar(b"hello")

如果您指定了正确的参数类型,那就更好了:

from ctypes import cdll, c_char_p
foo_bar = cdll.LoadLibrary("./libfoo.so").Foo_bar
foo_bar.argtypes = [c_char_p]
foo_bar(b"hello\n")
foo_bar("hello\n")

运行时会输出以下内容:

hello
Traceback (most recent call last):
  File "foo.py", line 5, in <module>
    foo_bar("hello\n")
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

即后一个使用字符串而不是bytes 的调用会抛出。

【讨论】:

感谢您的回答,效果非常好!【参考方案2】:

您还可以使用wchar_t 类型直接在C++ 中处理Python3 字符串。在这种情况下,您需要在 C++ 中进行任何必要的转换,如下所示:

#include <iostream>
#include <locale>
#include <codecvt>

void bar(wchar_t const* aString)

    // Kudos: https://***.com/a/18374698
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> convert;

    std::cout << convert.to_bytes(aString) << std::endl;


extern "C" 
    void Foo_bar(wchar_t const* aString)
    
        bar(aString);
    

但是,您将失去 Python2 兼容性。

【讨论】:

以上是关于从python调用c++函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QT/python 从 Javascript 调用 C++ 函数?

从python调用c++函数

从python调用c++函数

使用 SWIG 包装对象从 C++ 调用 Python 函数的最简洁方法是啥

使用 C++ 指针调用 python 函数

从 C++ 调用 Python