0

私はac関数を次のように持っています:

extern "C"  __declspec(dllexport) MyStruct foo()
{
    MyStruct s = {0, 0}
    return s;
}

MyStruct は次のように定義されます。

struct MyStruct{
    uInt32   a;
    uInt32   b;
    void *   c;
};

そして、私はPythonで関数を呼び出そうとしていますが、常に次のようなエラーが発生します:

WindowsError: 例外: アクセス違反書き込み 0x00000000

構造体から void * c を削除すると、機能します...

では、void ポインタを返すにはどうすればよいですか? ありがとう!

4

4 に答える 4

3

これは、オブジェクトを返すための C コンパイラと ABI の ctypes ライブラリとの間の不一致が原因であることがほとんどです。Python コードを見ないと、問題の原因が戻り値の型の間違った Python 宣言によるものか、ctypes ライブラリのバグによるものか、または C コンパイラによって選択された非標準 ABI によるものかを判断するのは困難です。

最も移植性の高い動作については、次のように、out パラメーターを介してオブジェクトを返すように関数を変更することをお勧めします。

extern "C"  __declspec(dllexport) void foo(MyStruct *ret)
{
    MyStruct s = {0, 0}
    *ret = s;
}

そして、次のようにインターフェースします:

class MyStruct(ctypes.Structure):
    _fields_ = [("a", ctypes.c_uint),
                ("b", ctypes.c_uint),
                ("c", ctypes.c_void_p)]

mylib = ctypes.cdll.LoadLibrary('mylibrary')
foo = mylib.foo
foo.argtypes = [ctypes.POINTER(MyStruct)]

x = MyStruct()
foo(ctypes.byref(x))
# x should now have the return value from the C code
于 2012-07-23T22:13:50.160 に答える
1

を割り当てているかわかりませんvoid* c。私はそれをどこにも見ませんが、後でどこかで読み取られているようです (つまり、access violation writing 0x00000000NULL ポインター)。したがって、c逆参照する前に何かに初期化する必要があります。

の値がcたまたま0ここにあるように見えますが、そうである必要はありません。静的ストレージ期間がなく、初期化していない ( と でのみ初期化ab{0, 0}) ため、c任意の値を持つことができます。私のテストケースでは、 (リリースであっても)c初期化されたメモリ領域に存在することが起こります。0これは保証されません。

私はあなたが次のようなことをしているに違いない:

MyStruct s = foo();
*((some_type*)s.c) = some_value;  // BLAMOOO! c is uninitialized

戻り値を使用するコードを投稿していないため、これが私が提供できる最善の推測です。

于 2012-07-23T22:10:44.947 に答える
0

Python コードを示していただけると助かります。の構造体と戻り値の型を定義する必要がありますfoo

from ctypes import *

class MyStruct(Structure):
    _fields_ = [
        ('a',c_int),
        ('b',c_int),
        ('c',c_void_p)]

mydll = CDLL('mydll')
mydll.foo.restype = MyStruct

r = mydll.foo()
print r.a
print r.b
print r.c
于 2012-07-24T01:52:36.747 に答える
-2

構造体をスタックに割り当てるのではなく、ヒープに割り当ててポインタを返します。スタックに物を割り当てると、それらは短命です。つまり、サブルーチンから戻ると、マシンによって自動的に割り当てが解除されます。

検索malloc( man malloc) / ここを参照: http://linux.die.net/man/3/malloc

于 2012-07-23T22:01:38.760 に答える