我有一个我想用Python访问的自制C库。问题在于代码基本上由两部分组成,一部分是从多个文件读入数据的初始化,另一部分是只需要执行一次的计算。另一部分在循环中调用,并使用重复前生成的数据。为了这个功能,我想从python传递参数。我的想法是编写两个C包装函数,“init”和“loop” - “init”读取数据并返回一个void指针,指向一个“loop”可以与其他参数一起使用的结构从python开始。像Python ctype - 如何在C函数之间传递数据
void *init() {
struct *mystruct ret = (mystruct *)malloc(sizeof(mystruct));
/* Fill ret with data */
return ret;
}
float loop(void *data, float par1, float par2) {
/* do stuff with data, par1, par2, return result */
}
东西,我试过用Python调用“初始化”作为c_void_p,但由于“循环”改变一些“数据”和ctypes的空指针是不可改变的,这没有工作的内容。
我看到类似问题的其他解决方案似乎需要知道多少内存“初始化”将使用,我不知道。
有没有办法通过python将数据从一个C函数传递到另一个,而无需精确地告诉python究竟是什么或多少?或者有另一种方法来解决我的问题?
我试过(也失败了)编写了一个最小崩溃的例子,经过一些调试后发现我的C代码中有一个错误。感谢所有回复的人! 希望这可以帮助其他人,这里是一个排序最小的-工作版本(仍然没有独立的 '自由' - 对不起):
pybug.c:
#include <stdio.h>
#include <stdlib.h>
typedef struct inner_struct_s {
int length;
float *array;
} inner_struct_t;
typedef struct mystruct_S {
int id;
float start;
float end;
inner_struct_t *inner;
} mystruct_t;
void init(void **data) {
int i;
mystruct_t *mystruct = (mystruct_t *)malloc(sizeof(mystruct_t));
inner_struct_t *inner = (inner_struct_t *)malloc(sizeof(inner_struct_t));
inner->length = 10;
inner->array = calloc(inner->length, sizeof(float));
for (i=0; i<inner->length; i++)
inner->array[i] = 2*i;
mystruct->id = 0;
mystruct->start = 0;
mystruct->end = inner->length;
mystruct->inner = inner;
*data = mystruct;
}
float loop(void *data, float par1, float par2, int newsize) {
mystruct_t *str = data;
inner_struct_t *inner = str->inner;
int i;
inner->length = newsize;
inner->array = realloc(inner->array, newsize * sizeof(float));
for (i=0; i<inner->length; i++)
inner->array[i] = par1 + i * par2;
return inner->array[inner->length-1];
}
编译为
在pythoncc -c -fPIC pybug.c
cc -shared -o libbug.so pybug.o
运行:
from ctypes import *
sl = CDLL('libbug.so')
# What arguments do functions take/return?
sl.init.argtype = c_void_p
sl.loop.restype = c_float
sl.loop.argtypes = [c_void_p, c_float, c_float, c_int]
# Init takes a pointer to a pointer
px = c_void_p()
sl.init(byref(px))
# Call the loop a couple of times
for i in range(10):
print sl.loop(px, i, 5, 10*i+5)
这是一个linux .so共享库。我添加了一个全局空指针,将“ret”设置为指针,然后在“循环”中访问它,但仍然出现崩溃,看起来循环看不到“init”的结果。我会试着找出那里发生的事情。谢谢你的帮助! – Alex
就这样我清楚...是“ret”全局指针吗?如果不是你想要设置“global_ptr”=(mystruct *)malloc(...)。然后在循环中使用global_ptr。如果这就是你在做什么,你仍然有崩溃,我会看看它更深 – sedavidw