【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
很多人说python的效率比较低,主要是没有分清什么时候用python、什么时候用c。对于网络、gui或者业务层面的代码,用python是完全可以的。但是对于算法、演算或者性能相关的逻辑,必须用c或者c++实现。因此回到windows平台,学会用python调用dll程序,是十分有必要的。用python调用dll不复杂,做好这几步就可以了,
1、创建一个dll工程
就按照vs2017的要求,“新建”-》“项目”-》“Visual C++”-》“Windows 桌面”-》“动态链接库”,一步一步创建工程即可
2、添加额外的函数代码
extern "C"
{
_declspec (dllexport) int add(int a, int b)
{
return a + b;
}
_declspec (dllexport) int sub(int a, int b)
{
return a - b;
}
}
3、编译工程,检验是否生成dll文件
选择项目,右击,选择“重新生成解决方案”
4、开始编写python代码
import ctypes
lib=ctypes.cdll.LoadLibrary("Dll1.dll")
5、验证是否可以使用add函数、sub函数
print lib.add(1,2)
print lib.sub(1.2)
6、可以试试还没有实现的函数,会不会出现调用异常
比如print lib.mul(1,2)
7、继续测试,数据类型不一致是否发生异常
比如print lib.add(1.1, 2.2)
8、验证句柄信息是否正确
比如print lib
9、数据传递
目前python里面整数、字符串都是可以传递给c程序的
如果是复杂一点的数据结构,建议直接用字符串组装传递进去,c程序收到后用sscanf解析
反过来,如果c的结果传给python,一般函数的返回值可以传递出来的,因此是字符串的话,可以通过多次调用函数获取返回值的方法来解决
10、其他
如果是发布给客户的应用程序,最好是用pyinstaller封装下,再加上必要的资源文件、dll文件、config配置文件,这样就可以了
注1:
如果c和python之间只是简单的数据传输,那么整数和字符串就可以了
一旦不是简单的数据,那么最好使用python原生的api,这样处理的效率更高点
注2:
注意使用ctypes库
ctypes --- Python 的外部函数库 — Python 3.7.13 文档
注3:
#!/usr/bin/python
import sys
from ctypes import *
import ctypes
station_yundi = CDLL("./demo_charge.dll")
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def button1_click():
glb_id = int(edit1.text())
glb_ip = edit2.text()
glb_port = int(edit3.text())
station_yundi.start_charge(ctypes.c_int(glb_id), glb_ip.encode('ascii'), ctypes.c_int(glb_port))
def button2_click():
station_yundi.stop_charge()
app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
widget.setFixedSize(500,500)
widget.setWindowTitle("Charge Tool App")
label1 = QLabel(widget)
label1.setText("ID:")
label1.move(100,100)
edit1 = QLineEdit(widget)
edit1.move(200,100)
label2 = QLabel(widget)
label2.setText("IP:")
label2.move(100,200)
edit2 = QLineEdit(widget)
edit2.move(200,200)
label3 = QLabel(widget)
label3.setText("Port:")
label3.move(100,300)
edit3 = QLineEdit(widget)
edit3.move(200,300)
b1 = QPushButton("charge", widget)
b1.setCheckable(True)
b1.move(100, 400)
b1.clicked.connect(button1_click)
b2 = QPushButton("discharge", widget)
b2.setCheckable(False)
b2.move(300, 400)
b2.clicked.connect(button2_click)
widget.show()
sys.exit(app.exec())