簡體   English   中英

Python使用ctypes自定義結構調用C共享庫

[英]Python calling C Shared Library with ctypes custom structures

我在Linux系統上從Python調用C共享庫。

我遇到的問題是C庫中的函數將一個指向結構的指針作為參數。 然后mallocs內存為一個結構數組,用數據填充數組並返回。 所以我把這個函數定義為

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))

Bar包含由func分配的結構數。

無論我做什么,我都無法從Foo中獲取任何數據。 幾個月來,我嘗試了多種不同的變體。 我可以查看來自C庫的日志,我知道它正在獲取數據並返回它,但我似乎找不到從Python中提取數據的方法。

有什么想法嗎?

如果我從問題中的評論中得到'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分配的內存...

好吧,這只需要一些小的更新。

首先,您的參數聲明已關閉,但這可能無關緊要。 就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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM