Board logo

标题: [文件操作] DllCall,支持结构体,指针 [打印本页]

作者: caruko    时间: 2010-11-28 21:38     标题: DllCall,支持结构体,指针

DllCall.exe (Autoit编写) 300K

1: 默认情况下, DllCall 使用 'stdcall' 调用方式. 要使用 'cdecl' 方式调用,请在返回值类型后面加上 ':cdecl'DllCall "SQLite.dll" "int:cdecl" "sqlite3_open" "str" Database_Filename  "long*" 0
2: 默认情况下, DllCall尝试使用 ANSI 版本的函数名, 例如. MessageBoxA 为尝试调用 MessageBox 所得到的函数名. 要调用unicode 版本的函数,请使用 MessageBoxW;同时支持用函数序号代替函数名。
  1. echo 元素类型[num]=元素值,元素类型1[num]=元素值1;元素类型n[num]=元素值n...|DllCall "dll" "返回值类型" "函数名称"  "类型1" "参数1" ["类型n" "参数n"...]
复制代码
输入流不能带其它特殊符号,字符串值包含空格也无需引号,但不能包括半角“;,=”等字符。
参数可不带引号,但包括空格的字符串必须带引号。
dllcall参数类型:
none 没有值 (仅用作无返回值函数的返回类型)  
BYTE 8 位(bit)整数  
BOOLEAN 无符号 8 位(bit)整数
short 16 位整数
USHORT 无符号16 位整数  
WORD 无符号16 位整数  
int 32 位整数
long 32 位整数
BOOL 32 位整数
UINT 无符号 32 位整数
ULONG 无符号 32 位整数  
DWORD 无符号 32 位整数  
INT64 64 位整数
UINT64 无符号 64 位整数
ptr 常规指针(void *)
HWND 窗口句柄(指针)
HANDLE 一个句柄(指针)
float 单精度浮点指针数  
double 双精度浮点指针数
INT_PTR, LONG_PTR, LRESULT, LPARAM 一个大型整数指针.(目前x86,x64都可以使用).
UINT_PTR, ULONG_PTR, DWORD_PTR, WPARAM 一个大型无符号整数指针.(目前x86,x64都可以使用).
str ANSI 字符串(不能超过 65536 个字符).
wstr UNICODE 宽字符串, 不能超过 65536 字符.
* 传递一个其它类型(添加一个*到末尾.) 例如 "int*" 传递一个指针到 "int" 类型.
布尔值可以直接是 true,false,指针类型可以是0x开头的内存地址。
如:
指针:echo int;int;int;int|dllcall user32.dll int GetWindowRect hwnd 0x01470CBB ptr Default0 ,句柄地址也可以用dllcall调用API从返回值得到。
布尔值:dllcall user32.dll int getWindows bool true "bool" "False" str "hello word" int 255

数据结构:  如果要指定数据大小请在数据类型后面添加 '[大小]'如: char[128]
类型 详细信息
BYTE 8bit(1字节) 带符号字符(signed char)
BOOLEAN 8bit(1字节) 无符号字符(unsigned char)
CHAR 8bit(1字节) ASCII 字符(ASCII char)
WCHAR 16bit(2字节) UNICODE 宽字符(Wide char)
short 16bit(2字节) 带符号整数(signed integer)
USHORT 16bit(2字节) 无符号整数(unsigned integer)
WORD 16bit(2字节) 无符号整数(unsigned integer)
int 32bit(4字节) 带符号整数(signed integer)
long 32bit(4字节) 带符号整数(signed integer)
BOOL 32bit(4字节) 带符号整数(signed integer)
UINT 32bit(4字节) 无符号整数(unsigned integer)
ULONG 32bit(4字节) 无符号整数(unsigned integer)
DWORD 32bit(4字节) 无符号整数(unsigned integer)
INT64 64bit(8字节) 带符号整数(signed integer)
UINT64 64bit(8字节) 无符号整数(unsigned integer)
ptr 32/64位 无符号整数(unsigned integer) (依据使用的 x86 或 x64  的版本)
HWND 32bit(4字节) 整数(integer)
HANDLE 32bit(4字节) 整数(integer)
float 32bit(4字节) 浮点指针(floating point)
double 64bit(8字节) 浮点指针(floating point)
INT_PTR, LONG_PTR, LRESULT, LPARAM 32/64位 带符号整数(signed integer) (依据使用的 x86 或 x64 的版本)
UINT_PTR, ULONG_PTR, DWORD_PTR, WPARAM 32/64位 无符号整数(unsigned integer) (依据使用的 x86 或 x64 的版本)
结构创建方法如:
;=========================================================
;   创建数据结构
;   struct {
;       int             var1;
;       unsigned char   var2;
;       unsigned int    var3;
;       char            var4[128];
;   }
;=========================================================
  1. echo int var1;ubyte var2;uint var3;char var4[128]|dllcall ... (ptr/viod) Default0
复制代码
var1,var2,varn...是数据结构的元素名,因为无法调用它们,因此不是必须的,下面这样也可以:
  1. echo int;ubyte;uint;char[128]|dllcall ... (ptr/viod) Default0
复制代码
要调用前面创建的数据结构,在参数中按创建顺序使用 Default0 Default1 ... Default9 调用,最多可以创建10个结构体。
可以在参数中打乱顺序使用, 比如先Default2 再Default0 ,最后Default1

;=========================================================
;   设置数据结构中的数据
;   struct.var1 = -1;
;   struct.var2 = 255;
;   struct.var3 = INT_MAX; -1 将自动确定类型(unsigned int)
;   strcpy(struct.var4,"Hello");
;=========================================================
初始化结构体数据时,创建多元素的结构用半角“;”隔开,使用=赋值。
  1. echo int=-1;ubyte=255;uint=-1;char[128]=Hello|dllcall ...(ptr/viod) Default0
复制代码
创建多个数据结构用半角的“,”隔开,如:
  1. echo byte,ptr=0x0025de1a,dword=0,int=-1;ubyte=255;uint=-1;char[128]=Hello;byte=NULL|dllcall ...(ptr/viod) Default3
复制代码
该句创建了4个结构体,Default3 引用了第4个,有4元素结构体的指针。
注意:在多元素结构体中,如果有元素不赋值,必须使其=关键字NULL。
给结构体赋值时,如果使用BOOLEAN 类型,为了区别字符串类型,使用#true #false代表布尔值true,false;大小写任意。
如 BOOLEAN=#true,BOOLEAN=#FlAse,char[20]=False "最后的这个false是字符串"。

最后,输出结构体数据以及返回值:
1:在调用结构体时,在Defaultn前加一个@,如@Default0,表示在结果中输出该结构体数据。
2:当元素为 char[n] 时,返回的数据是字符串,当元素为 byte[n] 或 ubyte[n] 时,返回的数据为二进制数据类型,否则它总是返回一个数字。
3:如果dll返回值为整数时,程序自动设置%ERRORLEVEL%为该值,正常退出时为0,否者是-1。如:
  1. dllcall user32.dll int MessageBox hwnd 0 str "some text" str "some title" int 3
复制代码
选择否的%ERRORLEVEL%值7。

局限:
1:暂时只能使用最多30个参数。
2:因为该程序运行完毕总是自动释放内存(包括结构体),关闭dll句柄,所以部分dll无法做到想要的功能。比如我写它的初衷,调用winmm.dll播放mp3,结果只能做成阻塞程序不让它退出,然后打开命名管道接受控制命令。
3:做为一次运行的控制台程序,即使支持指针类型,能做到的功能也很有限,比如回调函数等;
4:结构体方面,也不支持数据结构嵌套。

PS:大家有什么建议以及测试到的BUG,欢迎留言。家里最近不能上网,而且编程非常业余,查不到更多资料来做测试。

http://bcn.bathome.net/s/tool/index.html?key=DllCall
作者: Batcher    时间: 2010-11-29 18:55

你说的是这两个吗?
http://bbs.bathome.net/thread-4349-1-1.html
http://bbs.bathome.net/thread-7209-1-1.html
作者: caruko    时间: 2010-11-30 16:03

Autoit就是这麻烦,编译后把解释器都带上去了,300k =.=
上传不上来,还要分割才行...

[ 本帖最后由 caruko 于 2010-11-30 16:19 编辑 ]
作者: caruko    时间: 2011-1-4 17:18

最近改做了 2 个 DLL调用程序...

一个 dllServer.exe ,后台运行的无窗口win32程序,运行时需要参数指定管道名,打开命名管道接受控制命令。

一个dllCilent.exe ,控制台程序,指定管道名打开命名管道,发送控制命令以及DLL调用参数;接收DLL运行结果,输出在CMD里。

总算完成通过它调用winmm.dll 播放音乐的初衷了,支持指针参数也可以获取指针,但创建、输出数据结构的功能暂时还不如第上面那个版本的完善。部分窗口控制的API已经运行成功了。

有点大,不上传了,有需要的短信我留邮箱。
作者: dingcool    时间: 2017-4-6 18:25

楼主有联系方式吗?对au3
指针真的搞不懂
作者: 老刘1号    时间: 2017-5-9 20:15

回复 3# caruko


    还好吧……AHK编译后带解释器都上1M了……




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2