这两天在改进我的瑞星离线包下载程序.
之前使用动态释放并调用ActiveX EXE的方式实现异步执行过程,本身并没有问题;
但是,在动态释放与注册上面,出了问题.
具体原因并不清楚,很郁闷.
正好在学WIN32汇编,于是就想,反正是调用API,应该与VB差不多,就开始看书设计这个DLL了.
建立线程,下载文件,这些都不是问题,的确很容易(MASM编译器,很多高级语言的特征)
但接下来就遇到一个问题了:
下载进度的返回.
最理想的,应该是使用回调函数,通知调用者.
但在汇编里,应该怎么做呢?
查书&问人后,终于搞定,其实也很简单:
只要得到了回调函数的指针,那么就可以如一般函数调用那样,先PUSH,后CALL.
比如,有一个VB里定义的回调函数:
public function vbCallback(byval var1 as long,byval var2 as long)as boolean
debug.print var1 & "/" & var2
end function
在使用时,就要把这个函数的地址传到DLL里面,然后就可以在DLL里调用这个函数了:
'DLL内函数
DownloadFile proc _FileUrl,_SaveFileName,_lpCallBack
'VB声明:
Public Declare Function DownloadFile Lib "DownUrl.dll" ( _
ByVal FileUrl As String, _
ByVal SaveFileName As String, _
ByVal FuncAddr As Long) As Long
VB里调用:
Call DownloadFile("http://xxx/index.htm","d:\index.htm",addressof vbCallback)
使用Addressof操作符后,就将vbCallback过程的地址传进了DLL里面去.
然后在DLL里面,就可以像调用一般API一样调用它了:
push 2 'var2
push 1 'var1
call _lpCallBack
此时,VB里的回调函数已经被调用了,成功地实现了回调.
本来就打算这样用了,结果在看书时,发现了一个"动态调用DLL内函数"的方法,里面有一个技巧,用得上,如下:
MASM提供了一个叫invoke的伪操作符,可以让调用API非常方便,不用自己去PUSH参数;
不过动态调用时,INVOKE无法识别动态载入的函数,因为没有在库里面声明它
因此,就可以自己手工声明一个函数型指针变量,再把载入的函数指针赋值给这个变量,就可以使用INVOKE了
具体代码:
_ProcCallBack typedef proto :dword,:dword ;定义为两个参数的函数类型
ProcCallBack typedef ptr _ProcCallBack ;定义回调函数类型的指针
完成上面两步后,就可以定义一个指针变量,用于保存函数地址:
lpCallBack ProcCallBack ? ;定义回调函数指针
只要把得来的指针放入lpCallBack中,就可以直接使用invoke来调用了:
invoke lpCallBack,1,2
最后,感觉WIN32汇编,在API的使用上,与VB好象没有太大的差别.
让我目前为止感觉到非常爽的就是,一是体积,二是指针.....
编译出来的文件非常小......爽~~~~
然后,想弄什么指针就弄什么指针,方便啊~~~~
想想以前在VB里面弄指针的那个痛苦......... 
现在太好了,哇哈哈哈哈哈哈哈哈哈哈~~~
加油!!!!! 
|