Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C+;返回指针向量上的指针+;Python的dll_Python_C++_Ctypes_Dllexport - Fatal编程技术网

从C+;返回指针向量上的指针+;Python的dll

从C+;返回指针向量上的指针+;Python的dll,python,c++,ctypes,dllexport,Python,C++,Ctypes,Dllexport,我已经成功地将指针返回到结构(包含 WCARTH*t*/COD>),从C++ dll到Python,像这样: C++代码: ... typedef struct myStruct{ wchar_t* id; wchar_t* content; wchar_t* message; } myStruct; DLLAPI myStruct* DLLApiGetStruct(){ myStruct* testStruct = new myStruct();

我已经成功地将指针返回到结构(包含<代码> WCARTH*t*/COD>),从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代码:

class MyPyStruct(Structure):
    _fields_ = [
        ("id", c_wchar_p),
        ("content", c_wchar_p),
        ("message", c_wchar_p)
        ]
...
...
myDLL = cdll.LoadLibrary('myDLL.dll')
myDLL.DLLApiGetStruct.restype = POINTER(MyPyStruct)
result = myDLL.DLLApiGetStruct().contents
print result.id, result.content, result. message# those are valid values
好的,这很好,问题是现在我需要返回指向这些结构的指针向量上的指针。我试过这个:

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;
}
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
}
最后一行中的值无效-我想这是内存中的一些随机部分。 这是我得到的错误:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-11: character maps to <undefined>
UnicodeEncodeError:“charmap”编解码器无法对位置0-11中的字符进行编码:字符映射到

A
vector
与C兼容,但需要向C调用方(或ctypes)传递第一个元素的地址。也就是说,您必须保持指向
向量的指针,以便稍后释放它。我认为从一开始就使用阵列会更好。您可以向函数传递一个
int
out参数来接收数组的长度。由于您正在使用
new
进行分配,请记住在分配失败时捕获
bad\u alloc
异常

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

C++:

循环遍历结果的示例:

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


仅供参考,将
\u T
宏与显式
wchar\u T
数组一起使用是不正确的。这是针对Microsoft的
TCHAR
类型,用于编译为ANSI与Unicode。使用
L“宽字符串文本”

非常感谢您的示例代码,它工作得非常完美。你能解释一下为什么在
p[i][0]
中有
[0]
p[i]
是一个指针。您可以选择使用
p[i].contents
或获取第0个元素。就像我说的,我宁愿使用结构数组。在这种情况下,
p[i]
将是一个
myStruct
实例。但我必须重写代码才能这样做。我想我应该更接近你已经拥有的。你能建议我如何以及在什么时候释放内存吗。我必须这样做,因为
result=newmystruct*[n],对吗?导出另一个函数以释放内存。它需要数组及其长度的参数。循环遍历数组以
delete[]
每个结构的
wchar\u t
数组,然后
delete
该结构。最后,
delete[]
数组本身。
from ctypes import *

class myStruct(Structure):
    _fields_ = [
        ("id", c_wchar_p),
        ("content", c_wchar_p),
        ("message", c_wchar_p)
    ]

myDLL = cdll.myDLL
myDLL.DLLApiGetArray.restype = POINTER(POINTER(myStruct))
myDLL.DLLApiGetArray.argtypes = [POINTER(c_int)]

n = c_int()
p = myDLL.DLLApiGetArray(byref(n))
n = n.value
>>> 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