使用python ctypes引用opaque类型

时间:2012-11-15 18:10:57

标签: python ctypes

我正在使用定义不透明类型的第三方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的方法?

2 个答案:

答案 0 :(得分:2)

我认为这是最简单的解决方案......

创建一个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')

然后我可以创建一个适当大小的缓冲区,并通过引用将它作为指向opaque类型的指针传递给函数。到目前为止,非常好。

答案 1 :(得分:0)

由于C不支持运行时反射,因此不可能使用ctypes获取大小,因为没有像Java或C#/ .Net那样在编译的二进制文件中存储有关类型的元数据。

正如你所说,获得大小的一种方法是创建一个简单的C程序,其中包含定义类型的标题,然后使用sizeof运算符打印出大小。更进一步,您可以使用C compiler written in Python编译和执行C代码,以便在执行Python代码时获得大小。您甚至可以通过遍历编译器提供的数据结构来获取它而无需实际执行结果。

那就是说,你确定自己需要创造记忆吗? C库经常提供一种创建其他函数操作的opaque类型的方法。 更新:从评论确定内存必须由呼叫者分配。