使用 Python 的 ctypes 调用涉及自定义类型的函数

Using Python's ctypes to call functions involving custom types

本文关键字:自定义 类型 函数 调用 Python ctypes 使用      更新时间:2023-10-16

我当前正在尝试使用Python 3.6的CTYPES模块从C 编写的库中调用函数。

假设我使用ctypes创建一个称为mylibrary的共享库对象:

# Python code
myLibrary = ctypes.CDLL(mylib.dylib)

我正在尝试从使用C 类拨打电话的库,而CTypes不可能拨打python呼叫myLibrary.class()->method()的python(请参阅此处)。

因此,我首先编写一些中间的C 代码,这些代码以非级别的形式"包装" C 类方法。例如,假设Math是其中之一,而Add()是其方法之一。我的中间包装器看起来像这样:

// C++ intermediate code
int Add(int num1, int num2){                // no reference to a class
    return Math()->Add(num1, num2);         // reference to a class
}
然后,我计划将此C 编译到共享库(Dylib文件)中,我可以在该文件中使用CTYPE在Python中拨打电话。例如:
# Python code
def add(num1, num2):
    myLibrary.add(num1, num2)

那是计划。

不幸的是,库中的许多方法都具有异国情调的论点和价值类型。有些只是使用typedef关键字创建的变体类型名称,而另一些则是外来结构。此外,原始C 代码中有一些列举。

我的问题是:使用CTYPES时如何处理自定义参数和值类型(以及枚举)?

查看CTYPES文档,我知道您必须为要调用的方法指定restypes和argtypes,但是当原始C 函数涉及异国类型和structs时,如何执行此操作?

我认为CTYPES文档可能会在第15.17.1.6节中阐明这一点。("使用您自己的自定义数据类型调用函数"),但它只是谈论要将自己的对象类型传递到C 功能的反向方案。


类似的问题很有帮助,但并非完全:

  • 如何将C 类与CTYPE一起使用?
  • 使用ctypes从python中获取C中的自定义数据类型的地址

请注意,CTYPES旨在调用 C 代码,而不是 c

由于您已经在编写包装纸,因此您只需要更改一件事 - 指定这些包装器功能具有 c linkage:

// C++ intermediate code
extern "C" int Add(int num1, int num2) {    // no reference to a class
    return Math()->Add(num1, num2);         // reference to a class
}

至于结构等,您应该为它们定义一个适当的 c 语言接口。为此提出ctypes包装器并不难。