找回密码
 会员注册
查看: 39|回复: 0

Python调用C语言动态库(DLL)结构体指针变量的方法

[复制链接]

7

主题

0

回帖

22

积分

新手上路

积分
22
发表于 2024-9-9 21:51:33 | 显示全部楼层 |阅读模式
文章目录前言一、如何生成C语言动态库DLL第一步:安装编译工具第二步:设计C代码第三步:编译成C语言动态库DLL二、如何使用C语言动态库第一步:python/pytorch调入DLL接口第二步:Python调用DLL函数第三步:Python测试函数三、完整程序与测试结果总结前言在使用python等进行数据处理时,有时需要使用C语言生成的动态库进行数据处理,比如有些算法已经用C语言实现,或有些函数处理python没有现成函数或速度很慢,这时使用C语言生成动态库DLL的方法比较容易解决,在一些前期算法验证或测试验证中(可以隐藏核心代码)比较实用。一、如何生成C语言动态库DLL第一步:安装编译工具生成C语言动态库DLL需要使用编译工具,VisualStudio(VS)是比较方便使用的工具,当然还可以使用GCC、intelCCompiler等。下面以VS作为示例来说明使用方法。安装VS请在**这里**下载并安装,安装过程较为简单,没有特殊设置。第二步:设计C代码为了说明Python如何调用C代码中的结构体(带指针)、指针、变量已经返回值处理等问题,C代码构造了如下的程序。首先建立一个test.h头文件,定义结构体和DLL库函数结构:#ifndef__TEST_H__#define__TEST_H__#define__EXTERN____declspec(dllexport)typedefstruct_struct_my_data{intx;inty;float*data;}stru_my_data;//testdllcfunction:bias+beta*din.data__EXTERN__stru_my_dataTest(stru_my_datadin,float*bias,floatbeta);#endif//__TEST_H__1234567891011121314151617再建立一个test.c的函数实现文件如下://allfunctionshouldbeaccessibleaftercompiledtodll#include#include#include"test.h"//testdllcfunction:bias+beta*din.datastru_my_dataTest(stru_my_datadin,float*bias,floatbeta){inti=0,j=0;stru_my_datadout={0};dout.x=din.x;dout.y=din.y;dout.data=(float*)malloc(sizeof(float)*din.x*din.y);//bias+beta*din.datafor(i=0;i%0.8f(err_esp)"\%(error_max,err_esp))return1else:print("Test%dSuccessful"%(i))return01234567891011121314151617181920三、完整程序与测试结果完整代码如下:#ThisisaprogramforCDLLfunctionstestimportctypesimportnumpyasnpimporttimetest_dll=ctypes.CDLL("./dll/test.dll")classStructData(ctypes.Structure):_fields_=[("x",ctypes.c_int),("y",ctypes.c_int),("data",ctypes.POINTER(ctypes.c_float))]#############################################################################DLLtest_dll.Test.argtypes=[StructData,ctypes.POINTER(ctypes.c_float),ctypes.c_float]test_dll.Test.restype=StructDatadefDllTest(data_in,data_bias,beta):[height,width]=data_in.shape[height_b,width_b]=data_bias.shape#checkifdata_in.shape!=data_in.shape:print('InputDataSize!=BiasDataSize.')exit(-1)#dindin_c=StructData()din_c.x=heightdin_c.y=widthdin_c.data=data_in.reshape(-1).ctypes.data_as(ctypes.POINTER(ctypes.c_float))#biasbias_c=data_bias.reshape(-1).ctypes.data_as(ctypes.POINTER(ctypes.c_float))#CDLLFunctiondout_c=test_dll.Test(din_c,bias_c,beta)#outputreshapedout=np.ctypeslib.as_array(dout_c.data,shape=(dout_c.x,dout_c.y))returndoutdefCheckDllTest(height=64,width=64,err_esp=1.0e-6,sim_num=100):foriinrange(sim_num):#randomdatafortestdata_in=np.random.rand(height,width).astype('float32')bias_in=np.random.rand(height,width).astype('float32')beta_in=np.random.rand(1).astype('float32')#numpyresultdout=bias_in+beta_in*data_in;#CDLLresultdout_c=DllTest(data_in,bias_in,beta_in[0])#compareerror=np.allclose(dout,dout_c,rtol=1.e-5,atol=err_esp,equal_nan=False)iferrorisFalse:error_max=np.max(dout-dout_c)print("TestError:maxerror=%0.8f>%0.8f(err_esp)"\%(error_max,err_esp))return1else:print("Test%dSuccessful"%(i))return0#############################################################################MAINif__name__=="__main__":height=16width=16sim_num=10print("PythonUSECDLLFunctionsTesting...")################################################st=time.time()ifCheckDllTest(height=height,width=width,err_esp=1.0e-8,sim_num=sim_num):print("TestError!")exit(-1)print("TestDone.[T]%.3f"%(time.time()-st))123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172测试结果正确总结以上Python调用C语言动态库(DLL)结构体/指针/变量的方法,基本可以满足一般的需求,对于一些应用即可以借助C语言的代码执行高效性和通用性,又可以使用Python的便利性等特性何乐而不为。特别是有些AI神经网络inference应用方面,可以借助C/CUDA/C++,再结合pytorchC扩展等加速开发周期。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-9 06:01 , Processed in 0.433499 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表