山西
400-650-7353
首页 > 计算机二级 > 【备考】VB语言考试技巧:VB动态调用外部函数的方法

【备考】VB语言考试技巧:VB动态调用外部函数的方法

2018-08-30 17:33:55 来源:互联网 荐:IT资料豪华升级版,点击加群领取

VB可以用Declare声明来调用标准DLL的外部函数,但是其局限性也很明显:利用Declare我们只能载入在设计时通过Lib和Alias字句指定的函数指针!而不能在运行时指定由我们自己动态载入的函数指针),不能用Declare语句来调用任意的函数指针。当我们想动态调用外部函数的时候,就必须考虑采用其他的辅助方法,来完成这个任务了。

在文章《VB真是想不到系列之三:VB指针葵花宝典之函数指针 》、《Matthew Curland的VB函数指针调用》、《利用动态创建自动化接口实现VB的函数指针调用》等文献中对此问题都进行了一定程度上的讨论,但是头绪都很繁琐,对我这样的菜鸟还有点深奥,在资料搜索过程中,找到通过在VB中调入汇编程序,比较简便的实现了这个功能,下面就是实现原理:

1)使用LoadLibrary加载DLL;

2)GetProcAddress获得函数指针;

以上两步得到了预加载函数的指针,但是VB中没有提供使用这个指针的方法。我们可以通过一段汇编语言,来完成函数指针的调用!

3)通过汇编语言,把函数的所有参数压入堆栈,然后用Call待用函数指针就可以了。

实现以上功能的主要程序:

′加载Dll

LibAddr = LoadLibrary(ByVal "user32")

′获得函数指针

ProcAddr = GetProcAddress(LibAddr, ByVal "MessageBoxA")

′原型为MessageBox(hWnd, lpText, lpCaption, uType)

′---以下为Assembly部分---

push uType

push lpCaption

push lpText

push hWnd

call ProcAddr

′--------------------

FreeLibrary LibAddr′释放空间

嘿,够简单吧!下面是动态调用MessageBoxA的源代码,上面的步骤被封装到RunDll32函数中,可放到模块(CallAPIbyName.bas)中:

Dim s1() As Byte, s2() As Byte

Dim ret As Long

s1 = StrConv("Hello~World", vbFromUnicode)

s2 = StrConv("VBNote", vbFromUnicode)

ret = RunDll32("user32", "MessageBoxA", hwnd, VarPtr(s1(0)), VarPtr(s2(0)), 0&)

CallAPIbyName.bas中的源代码:

Option Explicit

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long

Private Declare Function CallWindowProc Lib "User32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Public m_opIndex As Long ′写入位置

Private m_OpCode() As Byte ′Assembly 的OPCODE

Public Function RunDll32(LibFileName As String, ProcName As String, ParamArray Params()) As Long

Dim hProc As Long

Dim hModule As Long

ReDim m_OpCode(400 + 6 * UBound(Params)) ′保留用来写m_OpCode

′读取API库

hModule = LoadLibrary(ByVal LibFileName)

If hModule = 0 Then

MsgBox "Library读取失败!"

Exit Function

End If

′取得函数地址

hProc = GetProcAddress(hModule, ByVal ProcName)

If hProc = 0 Then

MsgBox "函数读取失败!", vbCritical

FreeLibrary hModule

Exit Function

End If

编辑推荐IT学习交流群:点击加群 571960479

加群备注:网站(限时赠送500G海量IT学习资料)

关注微信:山西优就业(ID:ujiuyesx)

回复:简历模板,即可领取

【各类行业的简历模板】

回复:安装包的名称,例:AI,即可领取

AI、DW、PS、AX、C4D等破解版软件

【小U将毕生绝学传授于你,打倒HR,轻松搞定CEO】

相关推荐:开学季好课1折购

【备考】VB语言考试技巧:控件数组的概念及建立

更多分享交流,礼品领取,海量干货,请扫描下方内部资料领取二维码,一不小心就爱上IT,成为了大佬!

免责声明:本文来源于网络,由网友提供或网络搜集,仅供个人交流学习参考使用,不涉及商业盈利目的。如有版权问题,请联系本站管理员予以更改或删除。谢谢合作!

热门标签: VB语言 调用外部函数

猜你喜欢

推荐阅读