我正在尝试返回结构,所以我可以在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天的时间来完成这项工作。
答案 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);