《vb动态加载dll的一个类-实现vb动态加载dll并动态调用dll导出的函数的一个方便办法.docx》由会员分享,可在线阅读,更多相关《vb动态加载dll的一个类-实现vb动态加载dll并动态调用dll导出的函数的一个方便办法.docx(6页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、vb动态加载dll的一个类,实现vb动态加载dll并动态调用dll导出的函数的一个方便办法自从会vb用调用动态库函数以来,我一直在想:如何动态的调用dll里的函数?网上有一个用CallWindowProc函数的方法,不过我还是喜欢自己有个办法.今天工夫不负有心人,我终于把我心中一直想的办法给实现了,干脆就往自己的空间上贴吧.错误的地方,希望可以得到有这方面的师傅给以指正,以求进步!对于系统api我没有尝试,如果调用约定相符,应该适用于对系统api的调用.我自己用c写个dll,然后在vb里写了这个类.以下代码只是我简单的实现,主要的是看实现的道理.vc代码:/我把dll文件名命名为:dll#in
2、clude #include #include #include stdafx.hBOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)return TRUE;extern C BOOL _declspec(dllexport) add(int a)MessageBoxA(NULL,运行在dll里!,成功,MB_OK);a=999;return 1; /vb代码:类代码:Private 状态标志 As BooleanPrivate 模块句柄 As LongPrivate 本地函数地址
3、备份(0 To 4) As BytePrivate 被替换函数的地址 As LongPublic Function 替换函数地址(模块名 As String, 函数名 As String, 本地函数地址 As Long) As Boolean If 0 = 本地函数地址 Then替换函数地址 = 0Exit FunctionEnd If 被替换函数的地址 = 替换函数地址Dim 函数地址 As LongDim a As LongDim 跳转指令(0 To 4) As Byte 加载模块模块句柄 = LoadLibrary(模块名)If 0 模块句柄 Then状态标志 = 1Else:替换函数地
4、址 = 0Exit FunctionEnd If检索函数地址函数地址 = GetProcAddress(ByVal 模块句柄, ByVal 函数名)If 0 函数地址 Then状态标志 = 1Else替换函数地址 = 0Exit FunctionEnd If计算跳转地址a = 函数地址 - (本地函数地址 + 5)构造跳转地址跳转指令(0) = 233a = WriteProcessMemory(-1, ByVal VarPtr(跳转指令(1), ByVal VarPtr(a), 4, 0)If 0 = a Then替换函数地址 = 0Exit FunctionEnd If先备份本地函数入口指
5、令a = WriteProcessMemory(-1, ByVal VarPtr(本地函数地址备份(0), ByVal 本地函数地址, 5, 0)If 0 = a Then替换函数地址 = 0Exit FunctionEnd If写入跳转指令a = WriteProcessMemory(-1, ByVal 本地函数地址, ByVal VarPtr(跳转指令(0), 5, 0)If 0 = a Then替换函数地址 = 0Exit FunctionElse:状态标志 = 1替换函数地址 = 1End IfEnd FunctionPublic Function 还原函数地址() As Boolea
6、nIf 0 = 状态标志 Then还原函数地址 = 0Exit FunctionEnd IfDim a As Longa = WriteProcessMemory(-1, ByVal 被替换函数的地址, ByVal VarPtr(本地函数地址备份(0), 5, 0)If 0 = a Then还原函数地址 = 0Exit FunctionElse:状态标志 = 0还原函数地址 = 1End IfFreeLibrary 模块句柄End FunctionPublic Function 当前状态() As Boolean当前状态 = 状态标志End Functionvb普通模块代码:读写内存的api函
7、数Public Declare Function WriteProcessMemory Lib kernel32 (ByVal hProcess As Long, ByVal _lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long加载模块的api函数Public Declare Function LoadLibrary Lib kernel32 Alias LoadLibraryA (ByVal lpLibFileName As String) As
8、 Long检索模块里函数地址的api函数Public Declare Function GetProcAddress Lib kernel32 (ByVal hModule As Long, ByVal lpProcName As String) As LongPublic Declare Function FreeLibrary Lib kernel32 (ByVal hLibModule As Long) As Long模拟一个函数与dll里,我们想调用函数类型和参数一致, 用类将函数的地址替换Public Function 测试函数(参数 As Long) As Boolean我们随便给返回0,因为这个指令将不会被程序执行到测试函数 = 0End Functionvb窗口模块代码:Private Sub Form_Load()Dim 模块名 As String, 函数名 As String模块名 = App.Path + /dll.dll模块名现在可以自己定了,自由了!函数名 = addDim p As BooleanDim aa As New Class1p = aa.替换函数地址(模块名, 函数名, AddressOf 测试函数)If p Then测试函数 0将会弹出对话筐:运行在dll里!aa.还原函数地址End IfEnd Sub