6

Linuxシステム上のPythonからC共有ライブラリを呼び出しています。

私が遭遇している問題は、Cライブラリ内の関数が引数として構造体へのポインタを受け取ることです。次に、構造体の配列のメモリをmallocし、配列にデータを入力して戻ります。だから私は関数を次のように定義しました

from ctypes import *
class myStruct(Structure):
    _fields_ = [("id", c_uint), "name", c_char*256)]

library.func.argtypes =  [POINTER(myStruct)]

それから私はそれをそのように呼びます:

Myfoo = myStruct
Foo = pointer(Myfoo)
Bar = library.func(Foo)
for i in range(Bar):
    print("id = %u, name = %s" % (Foo[i].id, Foo[i].name))

バーには、funcによって割り当てられた構造の数が含まれています。

何をしても、Fooからデータを取得することはできません。私はこれについて何ヶ月もの間、複数の異なるバリエーションを試しました。Cライブラリからログを見ることができ、データを取得して返すことはわかっていますが、Pythonからデータを抽出する方法が見つからないようです。

何かご意見は?

4

2 に答える 2

5

質問のコメントから「func」プロトタイプを正しく取得した場合、これは次のようになります。

Cコード

#include <stdlib.h>
#include <stdio.h>

struct Foo
{
    unsigned int id;
    char name[256];
};

__declspec(dllexport) int func(struct Foo **ppFoo)
{
    int i;
    struct Foo *foo = malloc(5 * sizeof(struct Foo));
    for(i=0;i<5;i++)
    {
        foo[i].id = i;
        sprintf_s(foo[i].name,_countof(foo[i].name),"Name#%d",i);
    }
    *ppFoo = foo;
    return 5;
}

Pythonコード

from ctypes import *
dll = CDLL('x')
class Foo(Structure):
    _fields_ = [
        ('id',c_uint),
        ('name',c_char*256)]

pfoo = POINTER(Foo)()
count = dll.func(byref(pfoo))
for i in xrange(count):
    print pfoo[i].id,pfoo[i].name

出力

0 Name#0
1 Name#1
2 Name#2
3 Name#3
4 Name#4

freeどういうわけか、割り当てられたメモリがまだ必要であることに注意してください...

于 2012-05-21T03:57:25.703 に答える
4

さて、これにはいくつかの小さな更新が必要です。

まず、引数の宣言がオフになっていますが、それはおそらく問題ではありません。python-c値変換機構に関する限り、ポインターはポインターです。最も正確なのはですがPOINTER(POINTER(myStruct))、物事を簡単にするために、次を使用してみましょう。

library.func.argtypes = [c_void_p]

myStruct次に、引数が指すインスタンスをわざわざ作成する必要はありません。有効なポインタとそのポインタが必要ですfunc実際のmyStructインスタンスを割り当てます。それでは、まず始めましょう:

Foo = ctypes.POINTER(myStruct)()

今、私たちはそれを呼び出すことができます。がありmyStruct*ますが、ポインタを渡すのでfunc変更できます。他のポインタオブジェクト全体を作成する必要はないので、ライターを使用しますbyref

Bar = library.func(byref(Foo))

これで、を繰り返すことができますFoo[i]

for i in range(Bar):
    print("id = %u, name = %s" % (Foo[i].id, Foo[i].name))
于 2012-05-21T03:59:12.590 に答える