繁体   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