将结构从 c++ dll 返回到 Python

Returning struct from c++ dll to Python

本文关键字:返回 Python dll c++ 结构      更新时间:2023-10-16

我正在尝试返回结构,以便我可以在Python中使用它。我是初学者程序员,所以请解释我做错了什么。我之前已经成功地返回了简单的 ctypes(bool,无符号 int),但结构对我来说太复杂了。这是我所拥有的:

DLLAPI.h

#define DLLAPI extern "C" __declspec(dllexport)
...
DLLAPI myStruct* DLLApiGetStruct();

DLLAPI.cpp

EDIT1:结构成员类型现在不是 Ttring,而是 wchar_t*,但我得到的错误是相同的

...
typedef struct myStruct{
    wchar_t* id; 
    wchar_t* content; 
    wchar_t* message;
} myStruct;
DLLAPI myStruct* DLLApiGetStruct(){
    myStruct* test = new myStruct();
    test->id = _T("some id"); 
    test->content = _T("some content"); 
    test->message = _T("some message");
    return test;
}

这是我的Python代码:

...
class TestStruct(Structure):
    _fields_ = [
        ("id", c_wchar_p),
        ("content", c_wchar_p),
        ("message", c_wchar_p)
        ]
class SomeClass(object):
    ....  
    def test(self):
        myDLL = cdll.LoadLibrary('myDLL.dll')
        myDLL.DLLApiGetStruct.restype = TestStruct
        result = myDLL.DLLApiGetStruct()
        print "result type: ", type(result)
        print "-"*30
        print "result: ",result
        print "-"*30
        print result.id # line 152

这就是我得到的:

    result type:  <class 'Foo.TestStruct'>
    ------------------------------
    result:  <Foo.TestStruct object at 0x027E1210>
    ------------------------------
    Traceback (most recent call last):
    ....
    ....
    ....
    line 152, in test
        print result.id
    ValueError: invalid string pointer 0x00000002

我用过的是std::wstring

输入 myStruct 应该是指针还是其他东西?请帮助我,我已经花了 5 天时间尝试完成这项工作。

正如其他人所解释的,该问题版本 1 的问题在于使用了 std::string,它不是互操作的有效类型。

查看问题的版本 2,您的 C++ 和 Python 声明不匹配。C++代码返回指向结构的指针,但 Python 代码期望按值返回结构。

您可以更改C++或 Python 以匹配另一个。

C++

DLLAPI myStruct DLLApiGetStruct()
{
    myStruct result;
    result.id = L"some id";
    result.content = L"some content";
    result.message = L"some message";  
    return result;
}

myDLL.DLLApiGetStruct.restype = POINTER(TestStruct)

显然,您只能应用这些更改之一!

请注意,在C++代码中,我选择使用带有 L 前缀的显式宽字符串,而不是 _T() 宏。前者与 wchar_t* 匹配,后者是 TCHAR 使用的。这些天我不推荐 TCHAR,除非你需要支持 Win98。

> http://docs.python.org/3.1/library/ctypes.html

c_wchar_p包含wchar_t *,而不是std::wstring

问题是你返回了一个包含std::string的结构,但你告诉 Python 这些类型是指向wchar_t的指针。这与在C++中执行以下操作具有相同的效果。

struct Foo
{
    std::string id; 
    std::string content; 
    std::string message;
};
struct Bar
{
    wchar_t* id; 
    wchar_t* content; 
    wchar_t* message;
};
Foo f;
Bar* = reinterpret_cast<Bar*>(&f);