4

C 関数に渡すために、Python で次のデータ型を構築する必要があります。

struct {
  unsigned a,b,c;
  char data[8];
};

ただし、構造体へのポインターではなく、データフィールドへのポインターを実際に関数に渡す必要があり、これを行う方法がわかりません。

これが私がこれまでに持っているものです:

from ctypes import *                                                           
class MyStruct(Structure):                                              
  _fields_ = [("a",c_uint), ("b",c_uint), ("c",c_uint), ("data",c_char*8)]
mystruct = MyStruct(0,1,8,"ABCDEFGH")
external_c_function(mystruct.data)

CIには次の機能があります:

int external_c_function(char *data) {
  int a = ((unsigned *)data)[-1];
  int b = ((unsigned *)data)[-2];
  int c = ((unsigned *)data)[-3];
  ...
}

問題は、関数が呼び出されると、「データ」が「ABCDEFGH」を正しく指すことですが、その前の構造体データの残りを取得しようとすると、ゴミになります。私は何を間違っていますか?mystruct は、実際の C 構造体のようにメモリに順次保持されていませんか? 配列で何かおかしいことが起こっているのではないかと思います: 私は実際にこのようなばかげたことをしていますか?

struct {
  unsigned a,b,c;
  char *data; // -> char[8]
};

もしそうなら、どうすれば正しく行うことができますか?

4

2 に答える 2

5

要素のオフセットを使用して、参照によって構造体の要素へのポインターを渡します。

external_c_function(byref(mystruct,MyStruct.data.offset))
于 2012-11-15T04:36:28.090 に答える
2

を参照mystruct.dataすると、データのコピーが作成されるようです。これは、python コマンドが C 型ではなくtype(mystruct.data)を返すためです。str

external_c_functionこれが最も明白な解決策であるため、構造体の先頭でポインターを受け入れるように変更することはできないと思います。したがって、何らかの方法で Python で C スタイルのポインター演算を行う必要があります。つまり、mystruct(おそらく を使用してctypes.pointer) のアドレスを取得し、このポインターを適切なバイト数だけインクリメントする方法を見つけます。

Pythonでそのようなポインタ演算を行う方法、または堅牢な方法で行うことさえ可能かどうかはわかりません。external_c_functionただし、必要なポインター演算を行う別の C 関数をいつでもラップできます。

編集

マークの答えは問題をきちんと解決します。エラーが発生する理由についての私のコメントはまだ正しいです。

于 2012-11-15T04:23:59.010 に答える