2

私はctypesで奇妙な問題を抱えています。それによって、あるべきではないときにポインターを逆参照することによってスタックが破損しているように見えます。少しの間私と一緒にいると、セットアップはかなり複雑になります。

qfsm_search私はこのようなラップされた署名を持つC関数を持っています:

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

次に、CIで次のような機能があります。

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ポインターを渡すときに説明した動作のため、これはありそうにないようです。

私がWindows764ビットとPython2.6.4を実行していることはおそらく言及する価値があります。また、Python2.7.3での動作を再現することもできました。

どうもありがとう

4

1 に答える 1

0

これ以上お役に立てず申し訳ありませんが、C側に「OutNum」として受信された「0000005」があることをお勧めします。これは、max/にあるはずの「5」と同じである可能性があります。制限パラメータ-(破損したメモリで64ビット整数として表示される「5」の確率は非常に小さいです)。その場合、ctypesは、ポインターサイズに予想される8バイトを超える12〜16バイトを追加します。

おそらくすでに持っていますが、Python側の「skel」オブジェクトの定義を再確認してください。特に、正しく機能している「fsm」オブジェクトと比較してください。ヒントが得られない場合は、貼り付けてください。質問の更新に関する両方の宣言で見つかった違い。

于 2012-11-07T20:13:22.877 に答える