ctype,python通过ctype调用c/c++的dll动态库
参考文档ctypes — Python 的外部函数库
1.准备dll
1.cpp端,工程名cpp_native
1.CMakeLists.txt
cmake_minimum_required(VERSION3.14)project(cpp_native_sort_int_arr LANGUAGES CXX)set(CUR_TARGET_NAME ${PROJECT_NAME})# 创建动态库目标add_library(${CUR_TARGET_NAME}SHARED src/sort_int_arr.cpp)2.CMakePresets.json
{"version":6,"configurePresets":[{"name":"mingw","displayName":"GCC 9.2.0 mingw32","description":"Using compilers: gcc, g++","generator":"MinGW Makefiles","binaryDir":"${sourceDir}/build/${presetName}","cacheVariables":{"CMAKE_C_COMPILER":"gcc","CMAKE_CXX_COMPILER":"g++","CMAKE_MAKE_PROGRAM":"mingw32-make","CMAKE_BUILD_TYPE":"Debug","CMAKE_EXPORT_COMPILE_COMMANDS":"ON"}}],"buildPresets":[{"name":"mingwbuild","displayName":"Build with MinGW","description":"Build the project using the mingw configure preset.","configurePreset":"mingw"}]}3.src\sort_int_arr.h
#ifndefSORT_INT_ARR_H#defineSORT_INT_ARR_H#ifdef__cplusplusextern"C"{#endif// 冒泡排序:重复交换相邻逆序元素,原地排序。voidbubble_sort(int*values,intlength);// 选择排序:每轮选择未排序区间的最小值,原地排序。voidselection_sort(int*values,intlength);#ifdef__cplusplus}#endif#endif4.src\sort_int_arr.cpp
#include"sort_int_arr.h"voidbubble_sort(int*values,intlength){for(inti=0;i<length-1;++i){for(intj=0;j<length-1-i;++j){if(values[j]>values[j+1]){inttemp=values[j];values[j]=values[j+1];values[j+1]=temp;}}}}voidselection_sort(int*values,intlength){for(inti=0;i<length-1;++i){intmin_index=i;for(intj=i+1;j<length;++j){if(values[j]<values[min_index]){min_index=j;}}if(min_index!=i){inttemp=values[i];values[i]=values[min_index];values[min_index]=temp;}}}2.编译cpp端cpp_native
cmake--presetmingw cmake--build--presetmingwbuild编译后可以看到如下输出,libcpp_native_sort_int_arr.dll已被生成
[ 50%] Building CXX object CMakeFiles/cpp_native_sort_int_arr.dir/src/sort_int_arr.cpp.obj [100%] Linking CXX shared library libcpp_native_sort_int_arr.dll [100%] Built target cpp_native_sort_int_arr2.python端
创建一个test_sort_dll.py,将dll复制到该py的同级目录下
from_ctypesimportCFuncPtrimportosimportctypesfromctypesimportCDLLfromtypingimportList DLL_PATH:str=os.path.join(os.path.dirname(__file__),"libcpp_native_sort_int_arr.dll")# 1 加载dlldefload_dll(dllPath:str)->CDLL:returnctypes.CDLL(dllPath)# 2 获取c语言的排序函数defget_sort_func(func_name:str,dll:CDLL)->CFuncPtr:# // 冒泡排序:重复交换相邻逆序元素,原地排序。# void bubble_sort(int* values, int length);# // 选择排序:每轮选择未排序区间的最小值,原地排序。# void selection_sort(int* values, int length);func:CFuncPtr=getattr(dll,func_name)func.argtypes=[ctypes.POINTER(ctypes.c_int),ctypes.c_int]func.restype=Nonereturnfunc# 3.1 将 Python list 转换为 c语言的 int 数组defpython_list_to_c_arr(data:List[int])->ctypes.Array:# 第一步:创建数组类型array_type=ctypes.c_int*len(data)# 创建一个可以容纳 5 个 int 的数组类型# 第二步:解包并初始化array=array_type(*data)returnarray# 3.2 将 c语言的 int 数组转换为 Python listdefc_arr_to_python_list(c_array:ctypes.Array,length:int)->List[int]:# 将 ctypes int 数组转换为 Python list。return[c_array[i]foriinrange(length)]if__name__=="__main__":dll:CDLL=load_dll(DLL_PATH)bubble_sort:CFuncPtr=get_sort_func("bubble_sort",dll)selection_sort:CFuncPtr=get_sort_func("selection_sort",dll)# 测试数据集 - 包含各种边界情况test_cases:List[List[int]]=[[5,1,7,33,99],# 普通数据[3,1,4,1,5,9,2,6],# 重复元素[10,9,8,7,6,5,4,3,2,1],# 逆序数据[42],# 单元素[],# 空数组[-3,7,0,-1,5],# 负数和零]print("bubble_sort")fortest_caseintest_cases:print("排序前",test_case)length:int=len(test_case)c_array:ctypes.Array=python_list_to_c_arr(test_case)bubble_sort(c_array,length)print("排序后",c_arr_to_python_list(c_array,length))print("selection_sort")fortest_caseintest_cases:print("排序前",test_case)length:int=len(test_case)c_array:ctypes.Array=python_list_to_c_arr(test_case)selection_sort(c_array,length)print("排序后",c_arr_to_python_list(c_array,length))