Returning struct from c++ dll to Python

余生颓废 提交于 2020-01-05 07:06:11

问题


I'm trying to return structure so I can use it in Python. I am beginner programmer so please explain me what am I doing wrong. I've succeeded to return simple ctypes earlier (bool, unsigned int) but struct is too complicated for me. This is what I have:

DLLAPI.h

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

DLLAPI.cpp

EDIT1: instead of TString, struct members type is wchar_t* now, but error I get is the same

...
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;
}

here is my Python code:

...
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

this is what I get:

    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 I've used is std::wstring

Should type in myStruct be pointers or something instead TString? Please help me, I've spend 5 days trying to make this work.


回答1:


As the others explained, the problem with version 1 of the question is the use of std::string which is not a valid type for interop.

Looking at version 2 of the question, your C++ and Python declarations do not match. The C++ code returns a pointer to the struct, but the Python code expects the struct to be returned by value.

You could change either C++ or Python to match the other.

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)

Obviously you must apply only one of these changes!

Note that in the C++ code I chose to use explicit wide strings with the L prefix rather than the _T() macro. The former matches wchar_t* and the latter is what you use with TCHAR. I would not recommend TCHAR these days, unless you need to support Win98.




回答2:


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

c_wchar_p contains wchar_t *, not std::wstring




回答3:


The problem is you are returning a structure containing std::string's but you are telling Python that the types are pointers to wchar_t. This has the same effect as doing the following in 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);


来源:https://stackoverflow.com/questions/20773602/returning-struct-from-c-dll-to-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!