简体   繁体   English

从python调用c ++函数

[英]Calling c++ function from python

I'm trying to call a C++ function from my Python code, if I pass a Boolean or an int it works perfectly, but if I send a string, it only prints the first character. 我试图从我的Python代码调用一个C ++函数,如果我传递一个布尔值或一个int它完美地工作,但如果我发送一个字符串,它只打印第一个字符。
I am compiling with: 我正在编译:

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

Here is the C++ and Python code: 这是C ++和Python代码:

Python: 蟒蛇:

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

c++: C ++:

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

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

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

I'm aware of the Boost Library, but i couldn't manage to download it, and this way works well excepts for strings. 我知道Boost Library,但是我无法下载它,这种方式很适合字符串。 Thank you for your help 谢谢您的帮助

The problem is that strings are passed as pointers to wchar_t wide characters in Python 3. And in little-endian system your string can be coded in binary as 问题是字符串是作为Python 3中wchar_t宽字符的指针传递的。在little-endian系统中,你的字符串可以用二进制编码

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

Which, when printed with %s will stop at the first null terminator. 当使用%s打印时,将停止在第一个空终止符处。


For UTF-8-encoded byte strings ( char * ) you need a bytes object . 对于UTF-8编码的字节字符串( char * ), 您需要一个bytes对象 For example: 例如:

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

or use bytes literals: 或使用字节文字:

lib.Foo_bar(b"hello")

Even better if you had specified the correct argument types: 如果您指定了正确的参数类型,那就更好了:

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")

when run will output the following: 运行时将输出以下内容:

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

ie the latter call that uses a string instead of bytes would throw. 即后者使用字符串而不是bytes调用会抛出。

You may also process Python3 strings in C++ directly using the wchar_t type. 您也可以使用wchar_t类型直接在C ++中处理Python3字符串。 In that case, you need to do any necessary conversions in C++ like this: 在这种情况下,您需要在C ++中进行任何必要的转换,如下所示:

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

void bar(wchar_t const* aString)
{
    // Kudos: https://stackoverflow.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);
    }
}

You will lose Python2 compatibility, however. 但是,您将失去Python2兼容性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM