近期学了一点Python,然后正好有一个手机同步工具方面的预研工作要完成。
要实现PC与手机的通信,首先要找到他们的通信协议,还好的是Android有完善的协议:ADB
ADB的代码是开源的,而且支持Windows平台,有现成的DLL可以调用:AdbWinApi.dll,AdbWinUsbApi.dll
好了,可以用VC搞定,但我想用Python试一下,于是开始了苦逼的查资料+实验的过程。
实验过程就不多说了,由于上面的两个DLL都是用C实现的,提供的头文件也是C语言的,所以有了下面这个python测试程序(Python2.7):
import ctypes #自定义的GUID结构,有兴趣的可以自己研究用uuid模块 class GUID(ctypes.Structure): _fields_ = [("Data1", ctypes.c_ulong), ("Data2", ctypes.c_ushort), ("Data3", ctypes.c_ushort), ("Data4", ctypes.c_ubyte*8)] #自己定义的一个结构体,便于使用DLL接口 class AdbInterfaceInfo(ctypes.Structure): _fields_ = [("class_id", GUID), ("flags", ctypes.c_ulong), ("device_name", ctypes.c_wchar*800)] def strGUID(GUID): string = '' string = string + '%x' % buff.class_id.Data1 + '-%x' % buff.class_id.Data2 + '-%x' %buff.class_id.Data3 string = string + '-%x' % buff.class_id.Data4[0] string = string + '%x' % buff.class_id.Data4[1] string = string + '%x' % buff.class_id.Data4[2] string = string + '%x' % buff.class_id.Data4[3] string = string + '%x' % buff.class_id.Data4[4] string = string + '%x' % buff.class_id.Data4[5] string = string + '%x' % buff.class_id.Data4[6] string = string + '%x' % buff.class_id.Data4[7] return string dll = ctypes.cdll.LoadLibrary('AdbWinApi.dll') usb_class_id = GUID(0xF72FE0D4, 0xCBCB, 0x407d, (0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b)) enum_handle = dll.AdbEnumInterfaces(usb_class_id, ctypes.c_bool('true'), ctypes.c_bool('true'), ctypes.c_bool('true')) while(1): buff = AdbInterfaceInfo() size = ctypes.c_ulong(ctypes.sizeof(buff)) status = dll.AdbNextInterface(enum_handle, ctypes.byref(buff), ctypes.byref(size)) if status==1: #print "GUID = " + strGUID(buff.class_id) #print "status = " + str(status) #print "Name = " + str(buff.device_name) hAdbApi = dll.AdbCreateInterfaceByName(buff.device_name); if hAdbApi == 0: print 'AdbCreateInterfaceByName Fail' else: serial = ' '*128 pserial = ctypes.c_char_p() pserial.value = serial serial_len = ctypes.c_ulong(len(serial)) ret = dll.AdbGetSerialNumber(hAdbApi, pserial, ctypes.byref(serial_len), ctypes.c_bool('false')); if ret == 1: print 'Device Name: ' + '%s'% serial else: print 'Get Device Name Fail' else: print 'Finished' break import ctypes #自定义的GUID结构,有兴趣的可以自己研究用uuid模块 class GUID(ctypes.Structure): _fields_ = [("Data1", ctypes.c_ulong), ("Data2", ctypes.c_ushort), ("Data3", ctypes.c_ushort), ("Data4", ctypes.c_ubyte*8)] #自己定义的一个结构体,便于使用DLL接口 class AdbInterfaceInfo(ctypes.Structure): _fields_ = [("class_id", GUID), ("flags", ctypes.c_ulong), ("device_name", ctypes.c_wchar*800)] def strGUID(GUID): string = '' string = string + '%x' % buff.class_id.Data1 + '-%x' % buff.class_id.Data2 + '-%x' %buff.class_id.Data3 string = string + '-%x' % buff.class_id.Data4[0] string = string + '%x' % buff.class_id.Data4[1] string = string + '%x' % buff.class_id.Data4[2] string = string + '%x' % buff.class_id.Data4[3] string = string + '%x' % buff.class_id.Data4[4] string = string + '%x' % buff.class_id.Data4[5] string = string + '%x' % buff.class_id.Data4[6] string = string + '%x' % buff.class_id.Data4[7] return string dll = ctypes.cdll.LoadLibrary('AdbWinApi.dll') usb_class_id = GUID(0xF72FE0D4, 0xCBCB, 0x407d, (0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b)) enum_handle = dll.AdbEnumInterfaces(usb_class_id, ctypes.c_bool('true'), ctypes.c_bool('true'), ctypes.c_bool('true')) while(1): buff = AdbInterfaceInfo() size = ctypes.c_ulong(ctypes.sizeof(buff)) status = dll.AdbNextInterface(enum_handle, ctypes.byref(buff), ctypes.byref(size)) if status==1: #print "GUID = " + strGUID(buff.class_id) #print "status = " + str(status) #print "Name = " + str(buff.device_name) hAdbApi = dll.AdbCreateInterfaceByName(buff.device_name); if hAdbApi == 0: print 'AdbCreateInterfaceByName Fail' else: serial = ' '*128 pserial = ctypes.c_char_p() pserial.value = serial serial_len = ctypes.c_ulong(len(serial)) ret = dll.AdbGetSerialNumber(hAdbApi, pserial, ctypes.byref(serial_len), ctypes.c_bool('false')); if ret == 1: print 'Device Name: ' + '%s'% serial else: print 'Get Device Name Fail' else: print 'Finished' break
上面这个简单的Python代码,可以通过AdbWinApi.dll和AdbWinUsbApi.dll这两个DLL来找到你PC上正连接着的Android设备。
只调用了3个DLL接口,但目的已经达到,可以得出下面的结论:
使用Python调用DLL的方式来实现ADB工具是可行的,当然麻烦是不会少的了。
写在最后,Python调用C写的DLL还是比较麻烦的,特别是参数传递,尤其是指针的处理,这方面还得依靠ctypes模块。。。

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

本文解释了如何使用美丽的汤库来解析html。 它详细介绍了常见方法,例如find(),find_all(),select()和get_text(),以用于数据提取,处理不同的HTML结构和错误以及替代方案(SEL)

本文比较了Tensorflow和Pytorch的深度学习。 它详细介绍了所涉及的步骤:数据准备,模型构建,培训,评估和部署。 框架之间的关键差异,特别是关于计算刻度的

Python的statistics模块提供强大的数据统计分析功能,帮助我们快速理解数据整体特征,例如生物统计学和商业分析等领域。无需逐个查看数据点,只需查看均值或方差等统计量,即可发现原始数据中可能被忽略的趋势和特征,并更轻松、有效地比较大型数据集。 本教程将介绍如何计算平均值和衡量数据集的离散程度。除非另有说明,本模块中的所有函数都支持使用mean()函数计算平均值,而非简单的求和平均。 也可使用浮点数。 import random import statistics from fracti

本文讨论了诸如Numpy,Pandas,Matplotlib,Scikit-Learn,Tensorflow,Tensorflow,Django,Blask和请求等流行的Python库,并详细介绍了它们在科学计算,数据分析,可视化,机器学习,网络开发和H中的用途

本文指导Python开发人员构建命令行界面(CLIS)。 它使用Typer,Click和ArgParse等库详细介绍,强调输入/输出处理,并促进用户友好的设计模式,以提高CLI可用性。

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

文章讨论了虚拟环境在Python中的作用,重点是管理项目依赖性并避免冲突。它详细介绍了他们在改善项目管理和减少依赖问题方面的创建,激活和利益。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3汉化版
中文版,非常好用

Dreamweaver Mac版
视觉化网页开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。