4

不透明な型を定義するサードパーティの C ライブラリを使用しています。

    foo_t

そして、その関数でこの型へのポインターを使用します。

    void foo_init(foo_t *foo);

典型的な使用法は、スタックに foo_t を割り当て、参照を渡すことです。

  {
    foo_t foo;

    foo_init(&foo);
    ...
  }

foo_init()を構成するものを知らずに ctypesを呼び出すにはどうすればよいfoo_tですか?

そのサイズのバッファを作成してキャストできることを知っていればと思いますsizeof(foo_t)が、ctypesでサイズを取得することは可能ですか?

ワンライナーの C プログラムを書くことができます。

    printf("sizeof(foo_t) = %zu\n", sizeof(foo_t));

その値を私のpythonにハードコードしますが、それは急いで醜くなります.ライブラリをアップグレードするたびに、自分のpythonソースに手を加える必要があります.

サイズ値をエクスポートするために python c-ext を作成するのが少しクリーンな方法ですが、これもライブラリのアップグレードごとに再コンパイルする必要があります。

このような不透明な型で ctypes を使用するためのレシピはありますか?

4

2 に答える 2

3

これが最も簡単な解決策だと思います...

C ファイル、たとえば foosizes.c を作成します。

    size_t SIZEOF_FOO = sizeof(foo_t);

そして、それを共有オブジェクトにコンパイルしますfoosizes.so。次に、Python スクリプトで:

    from ctypes import *
    foosizeslib = CDLL('foosizes.so')
    sizeof_foo = c_ulong.in_dll(foosizeslib, 'SIZEOF_FOO')

次に、適切なサイズのバッファーを作成し、参照によって、不透明型へのポインターとして関数に渡します。ここまでは順調ですね。

于 2012-11-15T22:25:35.673 に答える
0

C はランタイム リフレクションをサポートしていないため、ctypes でサイズを取得することはできません。これは、Java や C#/.Net で行われるように、型に関するメタデータがコンパイルされたバイナリに格納されないためです。

あなたが言ったように、サイズを取得する 1 つの方法は、型を定義するヘッダーを含む単純な C プログラムを作成し、sizeof 演算子を使用してサイズを出力することです。さらに一歩進んで、Python で記述された C コンパイラを利用して C コードをコンパイルおよび実行し、Python コードが実行されたときのサイズを取得できます。コンパイラによって提供されるデータ構造をたどることで、実際に結果を実行する必要なく、それを取得できる場合もあります。

そうは言っても、自分でメモリを作成する必要があると確信していますか? 多くの場合、C ライブラリは、他の関数が操作する不透明な型を作成する方法を提供します。 更新:コメントから、呼び出し元がメモリを割り当てる必要があることは確かです。

于 2012-11-15T18:37:40.823 に答える