使用Python ctypes运行C dll函数时出现问题(数组输出大小未知)
我试图使用PythoncTypes执行一个C函数,但我做错了什么 C函数最初使用MATLAB编码器从MATLAB转换为C代码。该函数将一个长度未定义的数组作为输出,该数组取决于输入 这是MATLAB代码:使用Python ctypes运行C dll函数时出现问题(数组输出大小未知),python,c++,c,matlab,ctypes,Python,C++,C,Matlab,Ctypes,我试图使用PythoncTypes执行一个C函数,但我做错了什么 C函数最初使用MATLAB编码器从MATLAB转换为C代码。该函数将一个长度未定义的数组作为输出,该数组取决于输入 这是MATLAB代码: function a = array_output(n) %$codegen if n > 2*pi a = 1:n; else a = [1,2,3]; end end 这是获得的C代码: void array_output(double n, emxArray_
function a = array_output(n)
%$codegen
if n > 2*pi
a = 1:n;
else
a = [1,2,3];
end
end
这是获得的C代码:
void array_output(double n, emxArray_real_T *a)
{
int i;
int loop_ub;
if (n > 6.2831853071795862) {
i = a->size[0] * a->size[1];
a->size[0] = 1;
loop_ub = (int)floor(n - 1.0);
a->size[1] = loop_ub + 1;
emxEnsureCapacity_real_T(a, i);
for (i = 0; i <= loop_ub; i++) {
a->data[i] = (double)i + 1.0;
}
} else {
i = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = 3;
emxEnsureCapacity_real_T(a, i);
a->data[0] = 1.0;
a->data[1] = 2.0;
a->data[2] = 3.0;
}
}
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
输出的data\u struct
包含正确大小的字段(data\u struct.size[1]
为50),但当我尝试访问data\u struct.data[0]
时,我得到以下错误:
ValueError: NULL pointer access
有人能帮我理解我做错了什么吗
--
示例实现(代码段):
void main(){
//这里是伪代码
emxArray_real_T*a;
emxInitArray_real_T(&a,2);
/*初始化函数“数组\输出”输入参数*/
/*调用入口点“array\u output”*/
阵列输出(5.0,a);
}
无效emxInitArray\u real\T(emxArray\u real\T**pEmxArray,整数尺寸)
{
emxInit_real________________________________;
}
无效emxInit_real_T(emxArray_real_T**pEmxArray,整数尺寸)
{
emxArray_real_T*emxArray;
int i;
*pEmxArray=(emxArray_real_T*)malloc(sizeof(emxArray_real_T));
埃姆沙雷=*彭沙雷;
emxArray->data=(双*)NULL;
emxArray->numDimensions=numDimensions;
emxArray->size=(int*)malloc(sizeof(int)*numDimensions);
emxArray->allocatedSize=0;
emxArray->canFreeData=true;
对于(i=0;isize[i]=0;
}
}
无效emxEnsureCapacity_real_T(emxArray_real_T*emxArray,int oldNumel)
{
纽努梅尔国际酒店;
int i;
作废*新数据;
if(oldNumel<0){
奥尔德努梅尔=0;
}
newNumel=1;
对于(i=0;inumDimensions;i++){
newNumel*=emxArray->size[i];
}
如果(newNumel>emxArray->allocatedSize){
i=emxArray->allocatedSize;
如果(i<16){
i=16;
}
而(我1073741823){
i=最大输入32;
}否则{
i*=2;
}
}
newData=calloc((unsigned int)i,sizeof(double));
如果(emxArray->data!=NULL){
memcpy(newData,emxArray->data,sizeof(double)*oldNumel);
如果(emxArray->canFreeData){
免费(emxArray->data);
}
}
emxArray->data=(双*)新数据;
emxArray->allocatedSize=i;
emxArray->canFreeData=true;
}
}
数组输出的第二个参数是emxArray\u real\u T*
,但是您试图通过值传递结构,就好像它只是一个emxArray\u real\u T
。要解决此问题,请将dll.array\u output.argtypes=[ctypes.c\u double,DataStruct]
更改为dll.array\u output.argtypes=[ctypes.c\u double,ctypes.POINTER(DataStruct)]
和dll.array\u output(50,ctypes.byref(data\u struct))
您的示例不可复制。缺少emxEnsureCapacity\u real\u T
的定义。如果您有一个用C编写的工作emxInitArray\u real\u T
函数,为什么您要用Python重写它,而不仅仅是调用它?@JosephSible Monica我已经编辑了我的帖子。如果您愿意,我可以分享关于您不使用emxInitArray\u real\u T
的问题的整个输出代码,我真的只想使用主函数array\u output
,并用Python完成剩下的部分。
ValueError: NULL pointer access
void main(){
// pseudo-code here
emxArray_real_T *a;
emxInitArray_real_T(&a, 2);
/* Initialize function 'array_output' input arguments. */
/* Call the entry-point 'array_output'. */
array_output(5.0, a);
}
void emxInitArray_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
emxInit_real_T(pEmxArray, numDimensions);
}
void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
emxArray_real_T *emxArray;
int i;
*pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
emxArray = *pEmxArray;
emxArray->data = (double *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc(sizeof(int) * numDimensions);
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i *= 2;
}
}
newData = calloc((unsigned int)i, sizeof(double));
if (emxArray->data != NULL) {
memcpy(newData, emxArray->data, sizeof(double) * oldNumel);
if (emxArray->canFreeData) {
free(emxArray->data);
}
}
emxArray->data = (double *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}