将struct从c ++ dll返回到Python

时间:2013-12-25 14:07:09

标签: c++ python struct ctypes dllexport

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

DLLAPI.h

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

DLLAPI.cpp

EDIT1:而不是TString,结构成员类型现在是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

我使用的TString是std :: wstring

应该在myStruct中键入指针还是其他东西而不是TString? 请帮助我,我花了5天的时间来完成这项工作。

3 个答案:

答案 0 :(得分:3)

正如其他人所解释的那样,问题的第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;
}

<强>的Python

myDLL.DLLApiGetStruct.restype = POINTER(TestStruct)

显然,您必须只应用其中一项更改!

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

问题是你要返回一个包含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);