前言:
Python语言有着易用上手快的优点,但是其最大的缺点是执行速度慢,特别是for循环嵌套,需要遍历大矩阵的情况,其性能与C/C++相差甚远,那么再遇到上述情况时python调用C接口可能是较优的选择。
1. python调用C生成的动态链接库dll,向c接口传递整数和list字符串类型:
python端的代码如下:
CustomDll = cp.cdll.LoadLibrary(r"D:\Project_code\CppProject\cpp_utils\x64\Release\_GetNoZeroLabelIDIndex.dll")
BatchSizeLoadData = CustomDll._BatchSizeLoadData
BatchSizeLoadData.argtypes = [cp.c_uint, cp.POINTER(cp.c_char_p)]
BatchSizeLoadData.restype = cp.c_bool
def setParameters(strParamList):
numParams = len(strParamList)
strArrayType = cp.c_char_p * numParams
strArray = strArrayType()
for i, param in enumerate(strParamList):
strArray[i] = param.encode("ascii")
BatchSizeLoadData(numParams, strArray)
if __name__ == "__main__":
list = ["1111", "dadsadas"]
setParameters(list)
C头文件代码:
extern "C" _declspec(dllexport) bool _BatchSizeLoadData(unsigned int count, char **params);
C源文件代码如下:
bool _BatchSizeLoadData(unsigned int count, char **params) {
for (int i = 0; i < count;i++)
{
printf("%s", params[i]);
}
return true;
}
2. python向C接口传递np.array类型
python文件:
def load_data_ctypes(batch_size, path_list, data_array, label_array):
CustomDll = cp.cdll.LoadLibrary(r"D:\Project_code\CppProject\cpp_utils\x64\Release\_GetNoZeroLabelIDIndex.dll")
BatchSizeLoadData = CustomDll._BatchSizeLoadData
BatchSizeLoadData.argtypes = [cp.c_uint, cp.POINTER(cp.c_char_p),
np.ctypeslib.ndpointer(dtype=np.float32, ndim=1, flags='CONTIGUOUS'),
np.ctypeslib.ndpointer(dtype=np.uint8, ndim=1, flags='CONTIGUOUS')
]
BatchSizeLoadData.restype = cp.c_bool
str_array_type = cp.c_char_p * batch_size
str_array = str_array_type()
for i in range(batch_size):
str_array[i] = path_list[i].encode("ascii")
BatchSizeLoadData(batch_size, str_array, data_array, label_array)
C接口声明:
extern "C" _declspec(dllexport) bool _BatchSizeLoadData(unsigned int unBatchSize, char **pchParams, float *pshData, unsigned char * puchLabel);
C语言中float是32bit,所以python参数也应该是32bit浮点类型
3.、python数据类型与c接口要对应:
python调用C++接口传参时参数类型(所占字节数)必须一致,如python中的np.float64对应的市C中的double类型,float32对应C中float类型,使用C中sizeof函数来查看C中数据类型所占字节数,参照下表c数据类型表。
numpy数据类型:
数据类型 | 描述 |
bool_ | 布尔(True或False),存储为一个字节 |
int_ | 默认整数类型(与Clong相同;通常是int64或int32) |
INTC | 与Cint(通常为int32或int64)相同 |
INTP | 用于索引的整数(与Cssize_t相同;通常是int32或int64) |
INT8 | 字节(-128至127) |
INT16 | 整数(-32768至32767) |
INT32 | 整数(-2147483648至2147483647) |
Int64的 | 整数(-9223372036854775808至9223372036854775807) |
UINT8 | 无符号整数(0到255) |
UINT16 | 无符号整数(0到65535) |
UINT32 | 无符号整数(0到4294967295) |
UINT64 | 无符号整数(0到18446744073709551615) |
float_ | float64的简写。 |
float16 | 半精度浮点:符号位,5位指数,10位尾数 |
FLOAT32 | 单精度浮点数:符号位,8位指数,23位尾数 |
float64 | 双精度浮点:符号位,11位指数,52位尾数 |
complex_ | complex128的简写。 |
complex64 | 复数,由两个32位浮点数(实部和虚部) |
complex128 | 复数,由两个64位浮点数(实部和虚部) |
C数据类型:
整数类型
下表列出了关于标准整数类型的存储大小和值范围的细节:
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1 字节 | -128 到 127 或 0 到 255 |
unsigned char | 1 字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字节 | 0 到 4,294,967,295 |
浮点类型
下表列出了关于标准浮点类型的存储大小、值范围和精度的细节:
类型 | 存储大小 | 值范围 | 精度 |
---|---|---|---|
float | 4 字节 | 1.2E-38 到 3.4E+38 | 6 位小数 |
double | 8 字节 | 2.3E-308 到 1.7E+308 | 15 位小数 |
long double | 16 字节 | 3.4E-4932 到 1.1E+4932 | 19 位小数 |