2 回答

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超3個(gè)贊
在 C++ 代碼中,簽名int getResults(..., float* oResults)
無(wú)法將分配的指針傳回調(diào)用者。線(xiàn)路
oResults?=?(float*)malloc(results.size()?*?sizeof(float));
在 getResults 中本地設(shè)置oResults
指針,而不影響調(diào)用者。為了輸出指針,您必須使用return
它或使用指針到指針參數(shù):int getResults(..., float** oResults)
。
在Python代碼中,我不熟悉ctypes,但它看起來(lái)float_values = POINTER(c_float)
是一個(gè)問(wèn)題。為浮點(diǎn)指針POINTER(c_float)
創(chuàng)建 Python類(lèi)型。您想要POINTER(c_float)()
創(chuàng)建這樣一個(gè)指針的實(shí)例(最初為空)。

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超2個(gè)贊
該float* oResults參數(shù)是按值傳遞的,因此不可能返回該參數(shù)中已分配的指針。相反,使用float** oResults.
另外,float_values = POINTER(c_float)是類(lèi)型,而不是類(lèi)型的實(shí)例。所以byref(float_values)相當(dāng)于無(wú)效的 C &(float*)。相反,您需要一個(gè)指針的實(shí)例POINTER(c_float)()(注意括號(hào))并通過(guò)引用傳遞它,類(lèi)似于 C float *p; func(&p)。這會(huì)將指針按地址傳遞給 C 函數(shù),然后函數(shù)可以將其修改為輸出參數(shù)。
這是一個(gè)簡(jiǎn)化的示例,僅關(guān)注int *oRescount和float** oResults參數(shù)。還需要一個(gè)釋放分配的函數(shù):
測(cè)試.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]
添加回答
舉報(bào)