2 回答
![?](http://img1.sycdn.imooc.com/54584d6100015f5802200220-100-100.jpg)
TA贡献1803条经验 获得超3个赞
在 C++ 代码中,签名int getResults(..., float* oResults)
无法将分配的指针传回调用者。线路
oResults = (float*)malloc(results.size() * sizeof(float));
在 getResults 中本地设置oResults
指针,而不影响调用者。为了输出指针,您必须使用return
它或使用指针到指针参数:int getResults(..., float** oResults)
。
在Python代码中,我不熟悉ctypes,但它看起来float_values = POINTER(c_float)
是一个问题。为浮点指针POINTER(c_float)
创建 Python类型。您想要POINTER(c_float)()
创建这样一个指针的实例(最初为空)。
![?](http://img1.sycdn.imooc.com/5458478b0001f01502200220-100-100.jpg)
TA贡献1804条经验 获得超2个赞
该float* oResults参数是按值传递的,因此不可能返回该参数中已分配的指针。相反,使用float** oResults.
另外,float_values = POINTER(c_float)是类型,而不是类型的实例。所以byref(float_values)相当于无效的 C &(float*)。相反,您需要一个指针的实例POINTER(c_float)()(注意括号)并通过引用传递它,类似于 C float *p; func(&p)。这会将指针按地址传递给 C 函数,然后函数可以将其修改为输出参数。
这是一个简化的示例,仅关注int *oRescount和float** oResults参数。还需要一个释放分配的函数:
测试.cpp
#include <vector>
#define API __declspec(dllexport)
extern "C" {
API int getResults(size_t *oRescount, float** oResults) {
std::vector<float> results {1.25,2.5,3.75,5.0}; // Simulated results
*oRescount = results.size(); // Return size of results
auto tmp = new float[results.size()]; // allocate
for(size_t i = 0; i < results.size(); ++i) // copy vector to allocation
tmp[i] = results[i];
*oResults = tmp; // return allocation
return 0;
}
API void freeResults(float* oResults) {
delete [] oResults;
}
}
test.py
from ctypes import *
dll = CDLL('./test')
dll.getResults.argtypes = POINTER(c_size_t),POINTER(POINTER(c_float))
dll.getResults.restype = c_int
def getresults():
oRescount = c_size_t() # instance to hold the returned size
oResults = POINTER(c_float)() # instance of a float* to hold the returned allocation.
err = dll.getResults(byref(oRescount), byref(oResults))
# oResults is a float* and it is possible to index past the end.
# Make a copy into a Python list slicing to the correct size,
# then free it so there is no memory leak.
results = oResults[:oRescount.value]
dll.freeResults(oResults)
return err,results
err,ores = getresults()
print(err,ores)
输出:
0 [1.25, 2.5, 3.75, 5.0]
添加回答
举报