python--ctypes模块:调用C函数_python

Python 的 ctypes 要使用 C 函数,需要先将 C 编译成动态链接库的形式,即 Windows 下的 .dll 文件,或者 Linux 下的 .so 文件

Windows 系统下的 C 标准库动态链接文件为 msvcrt.dll (一般在目录 C:\Windows\System32 和 C:\Windows\SysWOW64 下分别对应 32-bit 和 64-bit,使用时不用刻意区分,Python 会选择合适的)


载入动态链接库:

import platform
from ctypes import * #导入模块

if platform.system() == 'Windows':
libc = cdll.LoadLibrary('msvcrt.dll') #载入动态链接库
#Windows 系统下的 C 标准库动态链接文件为 msvcrt.dll
elif platform.system() =='Linux':
libc = cdll.LoadLibrary('libc.so.6')
#Linux 系统下的 C 标准库动态链接文件为 libc.so.6
#下面是加载dll方法:
#stdcall调用约定:两种加载方式 :Objdll = ctypes.windll.LoadLibrary("dllpath")和Objdll = ctypes.WinDLL("dllpath")
#cdecl调用约定:也有两种加载方式:Objdll = ctypes.cdll.LoadLibrary("dllpath")和Objdll = ctypes.CDLL("dllpath")
#stdcall调用约定:两种加载方式 :Objdll = ctypes.windll.LoadLibrary("dllpath")和Objdll = ctypes.WinDLL("dllpath")


 另外导入dll文件,还有其它方式如下

import platform
from ctypes import *

if platform.system() == 'Windows':
libc = cdll.LoadLibrary('msvcrt.dll')
#libc = windll.LoadLibrary('msvcrt.dll') # Windows only
#libc = oledll.LoadLibrary('msvcrt.dll') # Windows only
#libc = pydll.LoadLibrary('msvcrt.dll')

#libc = CDLL('msvcrt.dll')
#libc = WinDLL('msvcrt.dll') # Windows only
#libc = OleDLL('msvcrt.dll') # Windows only
#libc = PyDLL('msvcrt.dll')
elif platform.system() =='Linux':
libc = cdll.LoadLibrary('libc.so.6')
#libc = pydll.LoadLibrary('libc.so.6')

#libc = CDLL('libc.so.6')
#libc = PyDLL('libc.so.6')

libc.printf('Hello ctypes!\n')




ctypes 数据类型

ctypes 作为 Python 和 C 联系的桥梁,它定义了专有的数据类型来衔接这两种编程语言。如下表

python--ctypes模块:调用C函数_python_02


注:Python 中的类型,除了 None,int, long, Byte String,Unicode String 作为 C 函数的参数默认提供转换外,其它类型都必须显式提供转换。

None:对应 C 中的 NULL

int, long: 对应 C 中的 int,具体实现时会根据机器字长自动适配。

Byte String:对应 C 中的一个字符串指针 char * ,指向一块内存区域。

Unicode String :对应 C 中一个宽字符串指针 wchar_t *,指向一块内存区域


音量控制: 

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from lianxi import Ui_Form
from PyQt5.QtCore import Qt
import platform
from ctypes import * #引入ctypes库
import ctypes


class Win(QWidget,Ui_Form):
def __init__(self):
super(Win, self).__init__()
self.setupUi(self)
self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint) # 窗体不能调整大小
self.setWindowTitle('练习')

if platform.system() == 'Windows':
libc = cdll.LoadLibrary('msvcrt.dll')

else:
exec(0)
self.user32 = ctypes.windll.user32 # 加载user32.dll并返回对象


def lianxi1(self):
APPCOMMAND_VOLUME_UP=0xa0000
APPCOMMAND_VOLUME_DOWN=0x090000
APPCOMMAND_VOLUME_MUTE=0x080000
hwnd = self.user32.GetForegroundWindow() # 获取最前窗口句柄
#self.user32.PostMessageA(hwnd,0x319,0,APPCOMMAND_VOLUME_UP) #增加系统音量2%
#self.user32.PostMessageA(hwnd, 0x319, 0, APPCOMMAND_VOLUME_DOWN) #减小系统音量2%
self.user32.PostMessageA(hwnd, 0x319, 0, APPCOMMAND_VOLUME_MUTE) #系统静音
#第一次静音 第二次还原
#参数4说明:https://technet.microsoft.com/zh-tw/sysinternals/ms646247(v=vs.71)

if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Win()
demo.show()
sys.exit(app.exec_())




python--ctypes模块:调用C函数_python_03





python--ctypes模块:调用C函数_python_04