从 Python 调用 C++ 64 位共享库

Calling C++ 64bit shared library from Python

我想使用来自 python 2.7.8 的给定 C++ 64 位共享库(linux 下的 .so 文件)中的函数。

C++共享库的

The header有这个函数:

EXPORT_CODE double CONVENTION PropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char *Ref);

我需要一个不需要修改共享库的 C++ 代码的解决方案(完整的 Python 包装器已经与自定义库一起存在)。

这是一个基于以下答案的有效解决方案:

>>> import ctypes
>>> lib = ctypes.cdll.LoadLibrary("/PathTo/libCoolProp.so")
>>> PropsSI = lib.PropsSI
>>> PropsSI.argtypes = (ctypes.c_char_p, ctypes.c_char_p, ctypes.c_double, ctypes.c_char_p, ctypes.c_double, ctypes.c_char_p)
>>> PropsSI.restype = ctypes.c_double
>>> result = PropsSI(b"H", b"T", 300., b"P", 101325., ctypes.create_string_buffer("Water", 8))
>>> result
112654.89965373254

还有另一种写法:

>>> from ctypes import *
>>> CoolProp = cdll.LoadLibrary('/PathTo/libCoolProp.so')
>>> PropsSI = CoolProp.PropsSI
>>> PropsSI.restype = c_double
>>> print PropsSI(c_char_p("H"), c_char_p("T"),c_double(300.),c_char_p("P"),c_double(101325.),c_char_p("Water"))
112654.899654

ctypes 会为你做很多类型转换。

例如,给定在 string.h

中定义的函数 strchr
const char * strchr ( const char * str, int character );

您可以提供函数的参数类型和 return 类型,而不必费心自己进行任何类型强制转换——ctypes 模块会为您处理。唯一的例外是当您需要将 char * 作为输出(可变)参数传递时。使用 ctypes.create_string_buffer 创建此参数,并使用 value 属性访问内容。

import ctypes

libc = ctypes.cdll.LoadLibrary("msvcrt")
# or on linux
# import ctypes.util
# libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c"))

strchr = libc.strchr

strchr.argtypes = (ctypes.c_char_p, ctypes.c_char)
strchr.restype = ctypes.c_char_p

result = strchr(b"abcde", b"c")
assert result == b"cde"

请注意 ctypes 如何自动将字符串参数转换为适当的类型,并且能够将 return 值转换回 python 字符串。