python start dll file

#coding=utf-8

#直接将代码放在 Pycharm中挨着看就明白:

"""总结:

1.python调用dll,必须客观根据dll原文件中声明的对应方式调用;

每个函数的入参和出参类型必须客观的根据原函数的入参和出参类型进行设置转化;
如果不清楚原函数出入参的类型,就不要谈python调用dll文件啦;
这里代码只是简单例子,没有涉及C++类,没有涉及dll文件中引用dll文件;
后面有很多参考文章,很不错的!
"""


import ctypes
from ctypes import *

"""第一步:加载dll文件(window系统是dll文件,Linux系统是.og格式文件)
   C语言中的函数默认是__cdecl调用,C++中可用__stdcall来显示声明调用,但也可以用extern “C”
   用python调用dll时需要根据不同的调用约定而使用不同的函数。但是不管什么调用,最后都必须用
   extern “C”来防止名字粉碎。
   目前ctypes下有两种方式加载,具体选择哪一种方式要根据dll源码里头文件即extern "C"
   {....}部分中声明的调用格式去调用选择加载方式:

常见:
__cdecl、、、---------对应用ctypes.CDLL(或cdll.LoadLibrary)
__stdcall、、、-------对应用ctypes.WinDll(或ctypes.windll.LoadLibrary)
"""

"""第一种加载方式"""
#dll=ctypes.CDLL('C:\\Users\\Administrator\\Desktop\\depends22_x86\\libtestdll.dll')
dll=cdll.LoadLibrary('C:\\Users\\Administrator\\Desktop\\depends22_x86\\libtestdll.dll')
#dll=ctypes.windll.LoadLibrary('C:\\Users\\Administrator\\Desktop\\depends22_x86\\libtestdll.dll')
#cdll.LoadLibrary和ctypes.CDLL效果一样
"""第二种加载方式"""
# dll = ctypes.windll.LoadLibrary( 'test.dll' )
# dll = ctypes.WinDll( 'test.dll' )
###其中ctypes.windll为ctypes.WinDll类的一个对象,已经在ctypes模块中定义好的。
#############################1---int整型(如果不加任何修饰,默认传入参数为int,传出参数也为int)#############
Double=dll.Double   #加载函数对象
Double.argtypes=[c_int]    #设置该函数入参类型,入参用[arg1,arg2,....]
#入参是int型或返回值是整型可不用进行设置(修饰)
print "int:",Double(4)
#上面三行和下面一行同样的效果
print "int:",dll.Double(c_int(4))

############################2---float型数据############################
floatAdd=dll.floatAdd      #加载函数对象
floatAdd.argtypes=[c_float,c_float]   #设置该函数入参类型,入参用[arg1,arg2,....]或(arg1,arg2,...)
floatAdd.restype=c_float              #这是该函数返回值类型
print floatAdd(1.4,3.45)
#上面四行和和下面两行一样
dll.floatAdd.restype=c_float
print dll.floatAdd(c_float(1.4),c_float(3.5))#注意由于返回值是float型,就必须先用floatAdd.restype=c_float声明返回类型

#############################3---字符串char#############################
"""
对于字符串char* ,在声明传入参数类型时,需要声明为字符指针,然后分配一块char数组,最后把这个数组强制转换为字符指针
并且,在把python脚本中的数据结构导入c++中时,需要把str转换为bytes或者bytesarray类型,并且进行迭代器分解
"""
charout=dll.charout
charout.argtypes=[c_char]  #传入参数为单字符
charout.restype=c_char       #返回值也为char型
print charout("a")
#或
dll.charout.restype=c_char
print dll.charout(c_char("a"))
#############################3---字符串char*#############################
"""
对于字符串char* ,在声明传入参数类型时,需要声明为字符指针,然后分配一块char数组,最后把这个数组强制转换为字符指针
并且,在把python脚本中的数据结构导入c++中时,需要把str转换为bytes或者bytesarray类型,并且进行迭代器分解
"""
hello=dll.HelloWorld
hello.argtypes=[c_char_p]    #传入参数为字符指针
STR=(c_char * 100)(*bytes("相信你还在这里!")) #把一组100个的字符定义为STR
cast(STR, POINTER(c_char))
hello(STR)

#############################4---int*#############################
Ints=dll.Ints
Ints.argtypes=[POINTER(c_int),c_int]
INT=(c_int * 100)(*[1,2,3]) #把列表传入变长参数args*中
cast(INT, POINTER(c_int))
Ints(INT,c_int(3))

 

 

参考文章1:

https://blog.csdn.net/u013639526/article/details/41724417 (函数调用规约(__stdcall 和 __cdecl 的区别浅析))

参考文章2:

https://docs.python.org/3.6/library/ctypes.html   (The Python Standard Library: ctypes)

参考文章3:

https://blog.csdn.net/mfq1219/article/details/81945448 (最全的ctypes总结)

参考文章4:

https://blog.csdn.net/mak0000/article/details/82387461 (python ctypes中文帮助文档)

参考文章5:

https://blog.csdn.net/yaningli/article/details/79948811 (python ctypes 的使用总结文档)

 

参考文章6:

https://www.jianshu.com/p/299c433f4e5d (python 调用dll的简单例子)

参考文章7:

https://blog.csdn.net/yaningli/article/details/79948811 (python ctypes 的使用总结文档)

 

Guess you like

Origin blog.csdn.net/weixin_42322206/article/details/102538871