Python ctypes 堆栈损坏

标签 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 指针段错误,并且打印任何调试信息。

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

可能值得一提的是,我正在运行 Windows 7 64 位和 Python 2.6.4。我还设法重现了 Python 2.7.3 上的行为

非常感谢

最佳答案

很抱歉无法提供更多帮助 - 但一个很好的提示是在 C 端收到的“0000005”作为“Out Num” - 我认为它可能与应该在最大/限制参数 - (“5”在损坏的内存中显示为 64 位整数的几率非常小)。如果是这种情况,ctypes 将在指针大小预期的 8 个字节之外额外放置 12 - 16 个字节。

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

关于Python ctypes 堆栈损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13275211/

相关文章:

Python 在传感器的 DLL 中调用 SDK 函数,该函数采用指针 IP 和端口并返回 void*(void* 配置文件传感器的句柄。)

python - Matplotlib 为所有图勾选无衬线字体

python - 使用 check_call 调用 shell 脚本

python - 如何使用 IP 地址 python 获取 MAC 地址

python - ctype问题字符**

python - ctypes通过读取文件初始化c_int数组

Python:如何在for循环中创建新变量?

python - 当随机列表返回空时,如何使用 itertools 和 fillvalue 压缩生成的列表?

python - 与 ctypes 的联合运算不起作用

python - 将字符串列表从 Python 传递给 Rust