使用 Python 的 ctypes 调用涉及自定义类型的函数
Posted
技术标签:
【中文标题】使用 Python 的 ctypes 调用涉及自定义类型的函数【英文标题】:Using Python's ctypes to call functions involving custom types 【发布时间】:2017-12-09 03:06:21 【问题描述】:我目前正在尝试使用 Python 3.6 的 ctypes 模块从用 C++ 编写的库中调用函数。
假设我使用 ctypes 创建了一个名为 myLibrary 的共享库对象:
# Python code
myLibrary = ctypes.CDLL(mylib.dylib)
我试图从中进行调用的库使用 C++ 类,并且 ctypes 无法进行myLibrary.class()->method()
形式的 Python 调用(请参阅here)。
因此,我首先编写一些中间 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 文件),我可以在该库上使用 ctypes 在 Python 中进行调用。例如:
# Python code
def add(num1, num2):
myLibrary.add(num1, num2)
这就是计划。
不幸的是,库中的许多方法都有奇异的参数和值类型。有些只是使用typedef
关键字创建的变体类型名称,但有些是奇异的结构。此外,在原始 C++ 代码中还有一些枚举。
我的问题是:在使用 ctypes 时如何处理自定义参数和值类型(以及枚举)?
查看 ctypes documentation,我知道您必须为尝试调用的方法指定 restypes 和 argtypes,但是当原始 C++ 函数涉及外来类型和结构时如何执行此操作?
我认为 ctypes 文档可能会在第 15.17.1.6 节中阐明这一点。 (“使用您自己的自定义数据类型调用函数”),但它只是讨论了您希望将自己的对象类型传递给 C++ 函数的相反场景。
有帮助但不完全的类似问题:
How to use C++ classes with ctypes? Obtaining address of custom data-type in C from Python using ctypes【问题讨论】:
【参考方案1】:请注意,ctypes 旨在调用 C 代码,而不是 C++。
由于您已经在编写包装器,您只需要更改一件事 - 指定这些包装器函数具有 C 链接:
// 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
包装器并不难。
【讨论】:
以上是关于使用 Python 的 ctypes 调用涉及自定义类型的函数的主要内容,如果未能解决你的问题,请参考以下文章