我有一个C函数,必须可以从C和Python调用。
我无法弄清楚如何传递python的c-type结构列表, 每个都包含几个嵌套的结构,到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 ]
我在上面使用的模型(将c-type指针传递给c-style结构到指向struct的指针的ac函数)似乎在我传入指向单个结构的指针时工作正常,但是,对于指向结构数组的指针,它似乎崩溃了。另外,我不确定python内存布局是什么结构列表与结构指针数组(正如C函数所期望的那样)。
非常感谢任何帮助!
更新:我发现以下链接非常有用: python ctypes array of structs
我解决了我的问题: 1.声明一个指向我的结构的指针数组:
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。修复接收指向struct array的指针的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中完全生成这个结构。)