回过头来,再看一下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对象的更多相关文章

  1. from声明

    在整个应用程序,只有三行声明.这是最短单WIN32应用,但它的功能是非常有限,简单地显示一个消息框,示出来,其他什么事情也没有做.以下就来分析这三行语句了.别小看这三行语句.其实是隐藏着非常多知识点在 ...

  2. cdll和windll的差别

    Python要想调用C语言写的动态连接库.不仅要兼容C接口的调用习惯,还须要兼容C语言的数据类型.幸运的是ctypes库已经做了这双方面的工作.以便调用动态连接库是很方便的.在Hello World的 ...

  3. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  4. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  5. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  6. Asp.Net WebApi核心对象解析(下篇)

    在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...

  7. JS核心系列:浅谈原型对象和原型链

    在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...

  8. Chrome出了个小bug:论如何在Chrome下劫持原生只读对象

    Chrome出了个小bug:论如何在Chrome下劫持原生只读对象 概述 众所周知,虽然JavaScript是个很灵活的语言,浏览器里很多原生的方法都可以随意覆盖或者重写,比如alert.但是为了保证 ...

  9. XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法

            在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...

随机推荐

  1. [51Nod]NOIP2018提高组省一冲奖班模测训练(二)

    http://www.51nod.com/contest/problemList.html#!contestId=73&randomCode=4408520896354389006 还是原题大 ...

  2. (转)Linux下使用rsync最快速删除海量文件的方法

    转自 : http://www.ha97.com/4107.html 昨天遇到了要在Linux下删除海量文件的情况,需要删除数十万个文件.这个是之前的程序写的日志,增长很快,而且没什么用.这个时候,我 ...

  3. Font Awesome 图标如何使用

    Font Awesome 图标如何使用 一.总结 一句话总结:Font Awesome字体图标非常好用,直接引入font-awesome.css,然后就可以直接使用了,使用的时候是用的i标签. 1.字 ...

  4. solr/lucence和关系数据库的混合使用

    我们知道solr提供了一个DIHandler,提供将关系数据库中的数据导成索引,然后使用solr查询. 对于一个大表中关联数个小表的查询,这非常耗费时间. 我的思路是: 1. 将一个大表做成索引,使用 ...

  5. C# 报表

    报表技术 1.OWC控件的使用 OWC是office web Components 是组件对象模型(COM)控件的集合,可用于将电子表格,图表和数据库发布到网站上. 在Office2003以后的版本中 ...

  6. error LNK2001: unresolved external symbol "public: virtual

    1) Mine solution : project-setting :static lib to shared dll .then ok. 找不到secondchar的定义, 你是否没有把包含sec ...

  7. 【CS Round #43 E】Coprime Pairs

    [链接]点击打开链接 [题意] 让你选择n个数字,组成一个数组,使得这n个数字中恰好有k对,它们是互质的. [题解] 我们可以先找出前n个质数,那么接下来的问题就转化为,凑出rest = n*(n-1 ...

  8. BC 52 div2 A Victor and Machine

    简单数学题,把这道题目贴上去的不过为了不想看到这个月写了某个数字篇博客,该数字有点不吉利... 近期没有学习的欲望.. . 集中不了注意力,今天打BC还是做出来一题,尽管涨分了,真心希望能接近cf的水 ...

  9. t_user is not mapped [from t_user as u where u.loginname = :loginname and u.password =:password]

    转自:https://blog.csdn.net/u010876380/article/details/52714539 错误: Struts Problem Report Struts has de ...

  10. jQuery的原理

    JQ的原理 jquery-1.xxx :专门为PC端诞生的类库,兼容所有的浏览器 jquery-2.xxx:当初是为了移动端而准备的,所以IE低版本浏览器一般不兼容,但是这个版本针对移动端的事件等操作 ...