我想使用来自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
答案 0 :(得分:2)
ctypes
会为你做很多类型强制。
例如,给定strchr
string.h
const char * strchr ( const char * str, int character );
您可以提供函数的参数类型和返回类型,而不必自己打扰任何类型强制 - ctypes
模块将为您处理此问题。唯一的例外是当您需要传递char *
作为out(可变)参数时。使用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
如何自动将字符串参数转换为适当的类型,并能够将返回值转换回python字符串。