将指针从C++ DLL返回到Python的指针返回

2024-09-30 16:26:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经成功地将指向struct(包含wchar_t*)的指针从c++dll返回到Python中,如下所示: C++代码:

...
typedef struct myStruct{
    wchar_t* id; 
    wchar_t* content; 
    wchar_t* message;
} myStruct;

DLLAPI myStruct* DLLApiGetStruct(){
    myStruct* testStruct = new myStruct();
    testStruct->id = _T("some id"); 
    testStruct->content = _T("some content"); 
    testStruct->message = _T("some message");
    return testStruct;
}

Python代码:

^{pr2}$

好的,这很好,问题是现在我需要返回指向这些结构的指针向量上的指针。我试过了:

C++代码:

typedef std::vector<myStruct*> myVector;
...
DLLAPI myVector* DLLApiGetVector(){
    myVector* testVektor = new myVector();
    for(i=0; i< 5; i++){
        myStruct* testStruct = new myStruct();
        testStruct->id = _T("some id"); 
        testStruct->content = _T("some content"); 
        testStruct->message = _T("some message");
        testVektor->push_back(testStruct);
    }
    return testVektor;// all values in it are valid
}

Python代码:

我认为第一行和第二行是不正确的(这是重新键入的正确方法吗?):

vectorOfPointersType = (POINTER(DeltaDataStruct) * 5)  #5 is number of structures in vector
myDLL.DLLApiGetVector.restype = POINTER(vectorOfPointersType)
vectorOfPointersOnMyStruct= myDLL.DLLApiGetVector.contents
for pointerOnMyStruct in vectorOfPointersOnMyStruct:
   result = pointerOnMyStruct.contents
   print result.id, result.content, result.message

最后一行中的值无效-我猜是内存中的一些随机部分。 这是我得到的错误:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-11: character maps to <undefined>

Tags: 代码inidmessagenewsomeresultcontent
1条回答
网友
1楼 · 发布于 2024-09-30 16:26:08

vector与C兼容,但需要向C调用方(或ctypes)传递第一个元素的地址。也就是说,您必须抓住指向vector的指针,以便稍后释放它。我想你最好从一开始就使用数组。可以向函数传递一个intout参数来接收数组的长度。由于您正在使用new进行分配,请记住,如果分配失败,请记住捕获一个bad_alloc异常。在

就个人而言,我会使用一个结构数组而不是一个指针数组,这样数据就在一个连续的块中。这将在ctypes中产生一个更干净的接口。对于指针数组,必须取消引用两次才能获取结构。在

C++:

#include <new>
#include <cwchar>

typedef struct myStruct {
    wchar_t *id;
    wchar_t *content;
    wchar_t *message;
} myStruct;

const wchar_t ID[] = L"some id";
const wchar_t CONTENT[] = L"some content";
const wchar_t MESSAGE[] = L"some message";

DLLAPI myStruct **DLLApiGetArray(int *size)
{
    int i, n = 5;
    myStruct **result;
    try {
        result = new myStruct *[n];
        for(i = 0; i < n; i++) {
            myStruct *tmp = new myStruct();
            tmp->id = new wchar_t[wcslen(ID) + 1];
            tmp->content = new wchar_t[wcslen(CONTENT) + 1];
            tmp->message = new wchar_t[wcslen(MESSAGE) + 1];
            wcscpy(tmp->id, ID);
            wcscpy(tmp->content, CONTENT);
            wcscpy(tmp->message, MESSAGE);
            result[i] = tmp;
        }
    } catch (std::bad_alloc &ba) {
        *size = -1; return NULL;
    }
    *size = n; return result;
}

Python:

^{pr2}$

循环遍历结果的示例:

>>> for i in range(n):
...     print i, p[i][0].id
...
0 some id
1 some id
2 some id
3 some id
4 some id

请注意,将_T宏与显式wchar_t数组一起使用是不正确的。这是针对Microsoft的TCHAR类型,用于编译为ANSI和Unicode。使用L"wide character string literals"。在

相关问题 更多 >