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.
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++.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++
Python
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.
http://docs.python.org/3.1/library/ctypes.html
c_wchar_p
containswchar_t *
, notstd::wstring