从 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 字符串。
我想使用来自 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 字符串。