Python ctypes堆栈损坏

时间:2012-11-07 17:43:41

标签: python ctypes

我遇到了ctypes的奇怪问题,因为它似乎是通过在不应该引用指针时解除引用来破坏堆栈。与我呆在一起的设置相当复杂。

我有一个带有包裹签名的C函数qfsm_search,如下所示:

qmotion.qfsm_search.argtypes = [
    qfsm_ptr,
    qfsm_node_t,
    qskel_ptr,
    vec3, c_int,
    qfsm_node_ptr,
    POINTER(c_int)]
qmotion.qfsm_search.restype = None

然后我输出参数的所有细节,并在python中调用它:

print("Fsm: %d | %X" % (sizeof(fsm), addressof(fsm.contents)))
print("Curr: %d | %d %d %d" % (sizeof(curr), curr.state, curr.anim, curr.frame))
print("Skel: %d | %X" % (sizeof(skel), addressof(skel.contents)))
print("Tar: %f %f %f" % (tar.x, tar.y, tar.z))
print("Limit: %i" % limit)
print("Out: %X" % addressof(out_nodes_p.contents))
print("Out Num: %X" % addressof(out_num_p.contents))

qmotion.qfsm_search(fsm, curr, skel, tar, limit, out_nodes_p, out_num_p)

这在python端输出以下内容。到目前为止,一切似乎都很好。

Fsm: 8 | 13CF0960
Curr: 12 | 0 0 89
Skel: 8 | 49193E60
Tar: 100.000000 100.000000 100.000000
Limit: 5
Out: 39A4FD10
Out Num: 2D623510

然后在C中我有这样的功能:

void qfsm_search(qfsm_t* fsm, qfsm_node_t curr, qskel_t* skel, vec3 tar, int max_out, qfsm_node_t* out, int* out_num) {

  qdebug("Fsm: %d | %p", (int)sizeof(fsm), fsm);
  qdebug("Node: %d | %d %d %d", (int)sizeof(curr), curr.state, curr.anim, curr.frame);
  qdebug("Skel: %d | %p", (int)sizeof(skel), skel);
  qdebug("Tar: %f %f %f", tar.x, tar.y, tar.z);
  qdebug("Max: %d", max_out);
  qdebug("Out: %p", out);
  qdebug("Out Num: %p", out_num);

  ....

但是这个功能输出:

Fsm: 8 | 0000000013CF0960
Node: 12 | 0 0 89
Skel: 8 | 000000000D6281A8
Tar: 0.000000 0.000000 14144512.000000
Max: 967112848
Out: 000000000D628468
Out Num: 0000000000000005

注意skel参数的值是如何更改的,以及在它损坏之后的堆栈。我认为ctypes取消引用skel参数的原因是,如果我将skel设置为NULL指针,那么在输入C函数并打印任何调试信息之前,我会得到一个NULL指针segfault。

有没有人知道可能会发生什么?我怀疑类型qskel_ptr可能有一些奇怪的问题,但这似乎不太可能,因为我在传入NULL指针时解释了这种行为。

值得一提的是,我运行的是Windows 7 64位和Python 2.6.4。我还成功地重现了Python 2.7.3上的行为

非常感谢

1 个答案:

答案 0 :(得分:0)

很抱歉没有能够提供更多帮助 - 但是有一个很好的提示,那就是“0000005”在C方面被收到“Out Num” - 我认为它应该是相同的“5” teh max / limit参数 - (在损坏的内存中出现为64位整数的“5”的几率非常小)。如果是这种情况,ctypes会将12-16个额外字节放在指针大小预期的8个字节之外。

您可能已经拥有,但是仔细检查Python端“skel”对象的定义 - 特别是将它与工作正常的工作“fsm”对象进行比较 - 如果没有给您提示,请在您的问题更新中粘贴您在两个声明中找到的任何差异。

相关问题