如何将结构列表/数组从python传递给C
我有一个C函数,必须可以从C和Python调用。
我无法弄清楚如何将c-cons结构的python列表传递给c函数,每个结构包含几个嵌套结构。
这些结构中的一个在python中看起来像这样:
class STATION_MM_NODE(ctypes.Structure): _fields_ = [ ("signal", MM_STRUCT), ("noise", MM_STRUCT), ("signalWindowLen", ctypes.c_double), ("metadata", SAC_PZ) ]
在C中像这样:
typedef struct stationMMnode { struct mantleMagStruct *signal; struct mantleMagStruct *noise; double signalWindowLen; SAC_PZ metadata; } stationMMnode_t;
采用stationMMnode结构数组的c函数可以调用为:
double magnitudeCompute_Mw_Mm_Event(stationMMnode_t **stationMMarray, int numStations);
例如,我可以将其称为纯粹来自C,如:
int testfunc() { stationMMnode_t *node1 = malloc(sizeof(struct stationMMnode)); node1->signalWindowLen = 500; stationMMnode_t *node2 = malloc(sizeof(struct stationMMnode)); node2->signalWindowLen = 100; struct stationMMnode *nodes[2]; nodes[0] = node1; nodes[1] = node2; magnitudeCompute_Mw_Mm_Event(nodes, 2); // Works! }
在python中,我可以创建一个类似于c数组结构的节点列表:
stationMMnodes = [] ... node = get_stationMMnode() # Returns a STATION_MM_NODE node.signal = mm_signal node.noise = mm_noise node.metadata = sacPoleZero stationMMnodes.append(node) ... wrap_lib.magnitudeCompute_Mw_Mm_Event(stationMMnodes, numStations) # Does NOT work
在哪里我将argtypes定义为:
wrap_lib.magnitudeCompute_Mw_Mm_Event.argtypes = [ctypes.POINTER(STATION_MM_NODE), ctypes.c_int ]
我在上面使用的模型(将ctype指针传递给c风格的结构到ac函数,它接受指向struct的指针)似乎在我传入指向单个结构的指针时工作正常,但是,对于指向一系列结构,似乎打破了。 另外,我不确定python内存布局是什么结构列表与结构指针数组(如C函数所期望的那样)。
任何帮助将不胜感激!
更新:我发现以下链接非常有用: python ctypes结构数组
我通过以下方式解决了我的问题:1。声明一个指向我的struct的指针数组:
nodeArrayType = ctypes.POINTER(STATION_MM_NODE) * 1024 nodeArray = nodeArrayType() nstn = 0
2.编写一个C函数将成员结构连接成一个更大的结构(=一个节点)并返回一个指向该结构的指针 – 它存储在nodeArray []中。
nodeArray[nstn] = wrap_libmth.libmth.makeNode(node.signal, node.noise, node.metadata) nstn += 1
3.修复接收结构数组指针的C函数的argtype:
wrap_libmth.libmth.magnitudeCompute_Mw_Mm_Event.argtypes = [ctypes.POINTER(ctypes.POINTER(STATION_MM_NODE)), ctypes.c_int]
所以…我有它的工作,但像Python的大多数事情一样,我觉得我抓住了老虎的尾巴,因为我不完全明白为什么它有效以及有什么(更好的)替代方案(例如, C hack makeNode()返回一个指向STATION_MM_NODE结构的指针不太令人满意 – 最好在python中完全生成这个结构。