??python3可以通过ctypes模块调用C++库,适当地混合使用将融合python和C++的优势,提升程序的性能。
??在ubuntu下,python3通过ctypes模块调用C++动态库,其中的关键在于数据的转换,在python3和C++之间通过ctypes模块将它们的数据联系在一起,在
官网资料中,可支持的数据类型如下:
ctypes类型 | c类型 | python类型 |
---|
c_bool | _Bool | bool | c_char | char | 单字符字节对象 | c_wchar | wchar_t | 但字符字符串 | c_byte | char | 整型 | c_ubyte | unsigned char | 整型 | c_short | short | 整型 | c_ushort | unsigned short | 整型 | c_int | int | 整型 | c_uint | unsigned int | 整型 | c_long | long | 整型 | c_ulong | unsigned long | 整型 | c_ulonglong | unsigned __int64或unsigned long long | 整型 | c_size_t | size_t | 整型 | c_ssize_t | ssize_t或Py_ssize_t | 整型 | c_float | float | 浮点数 | c_doulbe | double | 浮点数 | c_longdouble | long double | 浮点数 | c_char_p | char * | 字节串对象或None | c_wchar_p | wchar_t * | 字节串或None | c_void_p | void * | int或None |
??在上述数据结构中,可以看到只包含了基础的数据类型,如果传递大量的数据,可通过c_type_p传递字符串的方式进行,也可定义一些结构体传递数据。以下将用一个简单例子介绍通过传递json格式的字符串,程序下载链接为:https://gitee.com/jdi-shen/python-c
主要C++程序讲解
char* json_string() {
Json::Value root;
root["msg"] = "msg";
root["x"] = 2.5;
std::string json_str = Json::FastWriter().write(root);
static std::pair<char*, uint> c("", 0);
if(c.second != json_str.size()) {
if(c.second != 0) {
delete c.first;
}
c.first = new char(json_str.size());
c.second = json_str.size();
}
for(int i = 0; i < json_str.size(); i++) {
c.first[i] = json_str[i];
}
return c.first;
}
python3程序
import ctypes
lib = ctypes.cdll.LoadLibrary('../lib/libcpp_lib.so')
def convert_type(input):
ctypes_map = {int:ctypes.c_int,
float:ctypes.c_double,
str:ctypes.c_char_p
}
input_type = type(input)
if input_type is list:
length = len(input)
if length==0:
print("convert type failed...input is "+input)
return null
else:
arr = (ctypes_map[type(input[0])] * length)()
for i in range(length):
arr[i] = bytes(input[i],encoding="utf-8") if (type(input[0]) is str) else input[i]
return arr
else:
if input_type in ctypes_map:
return ctypes_map[input_type](bytes(input,encoding="utf-8") if type(input) is str else input)
else:
print("convert type failed...input is "+input)
return null
import json
import time
if __name__ == '__main__':
lib.add.restype = ctypes.c_double
print(lib.add(convert_type(3.0), convert_type(2.0)))
lib.json_string.restype = ctypes.c_char_p
print(lib.json_string())
lib.string_test.restype = ctypes.c_char_p
print(lib.string_test())
注意事项
- C++中的函数需要在声明处加入“extern “C” ”;
- jsoncpp的版本非常多,推荐使用gitee上的版本:https://gitee.com/openharmony/third_party_jsoncpp.git;
- python通过上述方式获得字符串后,会在字符串末尾增加一些不预期的字符,需要清除后再进行解析;
|