如何将结构列表/数组从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中完全生成这个结构。