Autohotkey-Dllcall神话篇(技术神话)

文:/ 飞跃作,河许人改

AHK界一直有这么一个故事,讲的是AHK星君和WIN大神之间通过小徒弟dllcall眉来眼去的故事。

神话.jpg

第一章

我是一个AHK星君(AHK脚本),居住在九重天上(硬盘),这九重天上由一位超级大神WIN大神(Windows系统)掌管,跟我一样的众神,每天各司其职,维持这乾坤的运转和平衡,我作为效率之神,每天幻化为亿万形态,解救人间低效之苦,深受人间的爱戴。

有一天我感应到强烈的召唤(被双击了),跳了起来说:WIN大神,我要临凡(运行),我要发威,我要表现了!WIN大神微微睁开双眼,“去吧!前途凶险(问题不好解决),受我加持(我这有好多宝贝你带上),方可顺利!”

“不用,老大你放心”

WIN大神没说话,大手一挥,云雾缭绕的九重天不见了,自由落体,好嗨呦!直奔一个蓝色的星球(内存)而去,一瞬间,我已经落地,站在一个写着“中国”的界碑前。

大神的声音响起,“这是你的活动空间(分配的内存),不准乱跑!这里我设了结界,别人也打扰不到你!”地上凭空出现一个方阵,有标准工人(栈)组成。“这些人,听你调遣,应付不了,随时打电话(dllcall)给我!”

说罢,工人扛起我,一路狂奔,直奔呼叫处。

第二章

一边走,一边想,“什么玩意,我一身法力(命令或函数)什么问题解决不了!”,说着,已经到了现场,经过一番苦战,竟然没能拿下,突然,WIN大神的最后一句话在我脑海中响起,CALL他!

于是,我拨了直通老大法宝管理处(WinAPI)的电话,刚一接通,管理处的领导说:“AHK星君啊!老大早料到你会打电话,让你小徒弟(dllcall()函数)过来拉吧!都给你准备好了(Dll文件)。”电话那头挂了。

“shit!”

“小D(dllcall()函数),去把法宝取过来!”

法宝在WIN大神准备好的Dll包裹中(Dll文件),也在某个星球中(硬盘),不一会儿,小D把它拉进地球(内存)的中国中,这是我的地盘,然后通过法宝名字(函数名)找到了法宝的位置,准备使用。

第三章

可是,WIN大神的法宝有点麻烦,要发动它需要给上面每个挂件(参数)都要一句咒语(声明),WIN大神的法宝特别多,挂件也特别多,每一个法宝挂不同的挂件效果还不一样,不过好在对应的咒语不多。

法宝只能通过标准工人(栈)来安装挂件(获取参数),我要把挂件(参数)一个个装入分配给标准工人(栈),每个挂件(参数)都是一个整数。补充一下,WIN大神分两种,一种是32位大神,他生产的标准工人每人能贡献四个单位(4个字节(1字节8位)),另一种是64位大神,他生产的标准工人每人能贡献八个单位(8个字节(1字节8位)),大神的法宝在制作时(编译),已经约定好按标准工人的能力(长度)来设计每个挂件(对齐每个参数),比如在64位大神的统治下(系统中),即使是安装一个1的挂件(传递参数1),它只需要1个单位的贡献,但是一个标准工人的8个贡献能力(8字节共有64位),根本用不完(另外63位要补0凑成64位装到集装箱中,所以输入参数的整数本来并不难,只要把参数的整数补齐到8字节装入集装箱即可。)

第四章

小D揼着法宝说,“每个挂件的都要咒语才能发动”(每个参数都要说明参数类型).

"我就纳闷了,不是约定好了一个标准工人装一个参数吗,干嘛还要念咒语呢(说明类型)?硬要我念得话,全部念最大那个咒语(使用集装箱的长度类型(Ptr))不行吗?"

小D小声说,大神让我给你传个话,大神的法宝调用有下面几种类型:

(1)第一种给它几个地址和小整数它就可以操作,这种法宝没必要叫你念咒语(特别说明类型)。

(2)第二种它需要一个特别大的整数(最大8字节),但是如果我们在32位大神那,每个标准工人只有4能力(字节),我就要把一个挂件(参数)的整数分给两个标准工人去做,这种情况你不是得用咒语(使用参数类型(int64))来喊一嗓子吗?你如果不喊,一个工人拿一半就走,法宝就没效果了(说明参数类型,我默认把这个参数装到一个集装箱中(大整数会截断一部分),把下一个参数装到下一个集装箱),如果你喊一嗓子(,而法宝声明了这个参数是64位的,)他们就知道咋回事了,两人一起搞一个挂件,这样后续的也不会乱了(它会读取连续两个集装箱拼成一个参数(下一个参数在这两个集装箱后面),后续参数不就错位了吗。)

(3)第三种它需要一个小数(浮点数)作为挂件(参数),因为标准工人里面只能装整数,所以小数是一种特殊构造的整数,系统约定好这个特殊整数的前面几位表示尾数部分,后面几位表示以2为底的指数部分,反正构造很复杂,小数1.0构造出的整数形式绝对不同于整数1的形式,如果你不说明这个参数是小数(float是4字节浮点数,double是8字节浮点数),我就不会进行特殊构造,直接取整传递整数,而法宝声明了这个挂件(参数)是小数,它会按照特殊构造来读取解析,不就搞错数字了吗。

(4)第四种它需要一个数据结构,也就是一个班级的座位结构,每个座位是一个字节,按它声明的规定,第一个数坐到第一个座位并占几个字节(霸占后续几个座位),第二个数坐到后面某个座位并占几个字节(霸占后续几个座位)等等,它需要你构造这么一个班级的座位结构,并把第一个座位的地址作为挂件(参数)分配给挂件。这种地址不用你操心挂件(参数)类型,因为地址的整数字节长度刚好等于标准工人的能力。你可以用VarSetCapacity()划分一个空闲的班级,用NumPut()把数字安放到各个座位上去,然后用 & 取班级第一个座位的地址作为参数。等法宝执行完毕后,它可能修改了某个座位上的数字,你可以用NumGet()从班级的某个座位中读取需要的数字。

(5)第五种它需要一个字符串,也就是一队字符小朋友,每个字符是一个编码的整数,它需要队伍的第一个字符的地址作为挂件(参数)装到分配给工人,本来你只要人工用 & 取队伍的第一个字符的首地址作为参数的整数即可,挂件(参数)类型不重要(Ptr即可),反正这个地址的长度刚好是一个工人的能力。但是我还是建议你使用Str类型,因为:

A、字符串有着特殊性,系统中使用的字符串有ANSI和Unicode两种编码方式,法宝到底需要哪一种,需要你自己判断及转换。声明Str参数类型而不是无所谓的类型(int、Ptr),我可以自动帮你转换(利用AStr和WStr类型转为法宝需要的编码)。

B、另外,法宝要求你输入一个地址,用于从这个地址输出一队字符串小朋友时,声明Str类型可以由我帮你自动读取字符串(更新字符串长度),否则要你自己手动读取字符串。(Str自动读取的情况AHK自身的编码与法宝名称指示的编码必须一致)

  • 注意:输出字符串必须由你先用VarSetCapacity()划分一个空闲的班级,才允许法宝在这个班级中输出数据,否则法宝输出的数据可能覆盖了你的其他地盘。

(6)第六种本来法宝可以有一个返回值,但是当它需要返回不止一个值时,它需要你在参数中提供一个地址,用来把某个结果数值写入到这个地址,等法宝执行结束后,你可以从这个地址中读取这个值。本来你可以手动用 & 取一个变量的地址作为挂件(参数)让工人去取,如果法宝需要这个地址中有个初值,可以用NumPut()把数字放入这个地址中,等法宝执行结束后,再用NumGet()从这个地址中读取返回值,这种方式参数类型不重要,反正这个地址的长度刚好适合一个标准工人的能力。但是我还是建议你使用类型,因为:使用类型可以由我自动地使用一个临时地址,先把初值写入,最后又把结果读出到你的参数的变量中,完全不用你操心,绝对推荐使用(Ptr*即可)。

好了,明白了小D(DllCall)讲述的这6种情况,你就会恰当的设定参数类型了。再学会:用 & 取变量地址、VarSetCapacity()、NumPut()、NumGet()、StrPut()、StrGet(),和根据A_PtrSize地址长度来计算数据结构的偏移,你就可以炉火纯青地使用DllCall了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,865评论 6 13
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,941评论 1 13
  • 内置函数Python解释器内置了许多功能和类型,总是可用的。他们是按字母顺序列在这里。 abs(x)返回一个数的绝...
    uangianlap阅读 1,223评论 0 0
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    JasonShi6306421阅读 1,228评论 0 1
  • 这年头,来一场说走就走的旅行,哪怕是去国外,已不是什么稀罕事了。出国旅游的好处显而易见:欣赏异域风景,领略异国文化...
    寻梦的孩子阅读 510评论 7 4