windll对象
回过头来,再看一下windll和oledll的差别,这两者之间最大的差别是oledll调用的函数都是固定返回HRESULT类型的值,而windll是不固定的类型的。在Python 3.3版本号之前,都是返回命名为OSError类型错误,在这之后就返回命名为WindowsError类型错误。
通一大段的讨论,我们彻底地了解cdll、windll和oledll之间的差别。为了更加清晰地记住它们,总结例如以下表所看到的:
表2-1:
|
对象名称 |
參数入栈顺序 |
清栈方式 |
返回值类型 |
|
cdll |
从右向左 |
调用者 |
不固定 |
|
windll |
从右向左 |
被调用者 |
不固定 |
|
oledll |
从右向左 |
被调用者 |
WindowsError |
windll对象
调用WIN32的API函数,主要是通过windll对象来实现。那windll是何许人也?因为Python是开源的项目,我们非常方便就定位到它的源代码库里,查看它的实现方式。这样对于了解windll背后的秘密带来了极大的方便,假设是商业的项目就比較艰难了。
在Milang或者Python的安装文件夹下,例如以下:
E:\Milang\python\Lib\ctypes
就能够找到ctypes库,这个库是通过包来公布的,因此在此文件夹下看到__init__.py文件。这个文件就是ctypes库导入时最初执行的文件,那么cdll、windll和oledll对象就是在这里创建的。与这里讨论相关的代码例如以下:
...
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
if _os.name in ("nt", "ce"):
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
else:
pythonapi = PyDLL(None)
if _os.name in ("nt", "ce"):
windll = LibraryLoader(WinDLL)
oledll = LibraryLoader(OleDLL)
...
通过这段代码能够看到,windll是LibraryLoader类的实例,它是一个WinDLL类型的对象。LibraryLoader的主要功能就是实现动态库连接库的搜索、载入和重载运算符。让在Python里使用动态连接库更加方便。到这里就能够来看这句代码的详细意思了:
MessageBox = windll.user32.MessageBoxW
windll就是前面创建的动态连接库载入对象,user32是Windows提供的WIN32的API接口的动态连接库的名称(user32.dll)。MessageBoxW是WIN32提供的弹出一个提示框的函数名称。在这行代码里。有意思的是并没有採用传送參数的方式来訪问不同的动态连接库。而通过属性的方式(点号执行)来选择不同的动态连接库。
在这里.user32就是表示訪问动态连接user32.dll。像以下这行代码:
windll.kernel32.GetModuleHandleW(None)
就是表示訪问动态连接库kernel32.dll,因此訪问动态连接库gdi32.dll,就是变成这样:
windll.gdi32
通过点号运算就能够方便地载入不同的动态连接库。这是因为LibraryLoader类在后面进行点号运算符进行重载的结果。这样使用起来更方便和更清晰,比传送參数打更少的代码。在Windows里主要提供以下三个动态连接来对Windows的功能调用。例如以下:
kernel32.dll是Windows9x/Me中非常重要的32位动态链接库文件,属于内核级文件。它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
user32.dll是Windows用户界面相关应用程序接口,用于包括Windows处理,基本用户界面等特性,如创建窗体和发送消息。
gdi32.dll是Windows GDI图形用户界面相关程序,包括的函数用来绘制图像和显示文字。
在这里有一点,你或许注意到了。当想调用MessageBox函数时,事实上是写的名称是MessageBoxW。在后面多了一个W。这个W是什么用的呢?事实上在WIN32的API里,提供了两套的API接口,一套是支持是UNICODE的API接口,一套是支持ANSI的API接口。说白了就是为了解决双字节和单字节的文字的显示问题。
因此,要想使用ANSI单字的API接口,要使用MessageBoxA的名称。
在我们编写C和C++程序时。仅仅须要使用MessageBox就能够了。事实上这是因为API在接口的头文件进行宏定义。在Python里没有必要进行这样的魔幻的操作,让人更加明了,明确。
windll对象的更多相关文章
- from声明
在整个应用程序,只有三行声明.这是最短单WIN32应用,但它的功能是非常有限,简单地显示一个消息框,示出来,其他什么事情也没有做.以下就来分析这三行语句了.别小看这三行语句.其实是隐藏着非常多知识点在 ...
- cdll和windll的差别
Python要想调用C语言写的动态连接库.不仅要兼容C接口的调用习惯,还须要兼容C语言的数据类型.幸运的是ctypes库已经做了这双方面的工作.以便调用动态连接库是很方便的.在Hello World的 ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- JS核心系列:浅谈原型对象和原型链
在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...
- Chrome出了个小bug:论如何在Chrome下劫持原生只读对象
Chrome出了个小bug:论如何在Chrome下劫持原生只读对象 概述 众所周知,虽然JavaScript是个很灵活的语言,浏览器里很多原生的方法都可以随意覆盖或者重写,比如alert.但是为了保证 ...
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
随机推荐
- DG Cascade Standby
SUMMARY 1. logical standby不支持cascading standby 2. 11.2.0.2之前版本cascading standby不支持RAC 3. 11.2.0.3之前版 ...
- Win8.1恢复这台电脑里的6个文件夹
平台:win8.1 问题:网络下载的ghost版8.1,装好后“这台电脑”里没有6个常用的文件夹. 解决:导入下列注册表项即可 Windows Registry Editor Version 5.00 ...
- vmware workstation安装windows server 2019
提示需要输入密钥,选择[我没有密钥] 选择有桌面体验的 自定义 新建C盘 100G 选择100G的主分区,下一步 PS:未分配的空间,先不理,安装完系统,进桌面,再分配 开始安装.接下来就是等. 等. ...
- SpringCloud核心教程 | 第三篇:服务注册与发现 Eureka篇
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...
- 洛谷 P1334 瑞瑞的木板
P1334 瑞瑞的木板 题目描述 瑞瑞想要亲自修复在他的一个小牧场周围的围栏.他测量栅栏并发现他需要N(1≤N≤20,000)根木板,每根的长度为整数Li(1≤Li≤50,000).于是,他神奇地买了 ...
- 洛谷 P1014 Cantor表
P1014 Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 ...
- 巧用数据流让 Word 文档在线阅读
常常写博客或空间日记的朋友,对网络编辑器(如图1,是CSDN的博客编辑器)并不陌生.也比較easy做出非常绚烂的排版.但这次在做一个BS的项目,客户一直在用Office的软件中的Wor ...
- shell-查看手机分辨率
使用如下命令,可以查看手机分辨率 adb shell dumpsys window displays 运行结果如下 Display: mDisplayId= init=1080x1920 480dpi ...
- imageView-scaleType 图片压缩属性
今天用到了图片压缩的属性,自己参照网上的说明,验证了一下,截图如下 (1)当图片背景是方形的时候 代码如下 <LinearLayout android:id="@+id/l31&quo ...
- JS学习笔记 - fgm练习 - 数字自增 定时器 数字比大小Math.max
<script> window.onload = function(){ var oP = document.getElementsByTagName('p')[0]; var i = 0 ...