【VB技巧】VB静态调用与动态调用dll详解
本文“【VB技巧】VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处!
【【请注意】】:在以下语法格式中,请注意 [函数名] 的【大小写】!!!
静态与动态比较:
静态调用简单,动态调用麻烦;静态调用占用资源多,动态调用占用资源少;正所谓鱼和熊掌不可兼得。
静态调用定义:
就是常用的申明API,一个DLL库里有很多的函数可供调用,把要用的申明即可。 比如:Public/Private Declare Function [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表) [As 返回值的数据类型] 示例:Private Declare Function Test Lib "dll.dll" (x As String) As String 当程序结束的时候系统回自动释放DLL调用。
动态调用定义:
使用LoadLibery(DLL名),系统会检查DLL是否调入内存。如果调入了,可直接调用DLL里的所有函数,没有就会把DLL加入目标进程的进程空间。通过函数GetProcAddress确定函数入口地址,然后调用,后一种方法VB里不常用的。
静态调用详解:
制作好DLL之后,首先用Declare声明语句在窗体级或模块级或全局模块的代码声明段进行声明,将动态链接库中的函数声明到VB中,供VB程序调用。
语法格式1: Public/Private Declare Sub [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表)
语法格式2: Public/Private Declare Function [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表) [As 返回值的数据类型]
在声明中首先用Declare关键字表示声明DLL中的函数。在C语言中有的函数类型为VOID,它表示不具有返回值,则必须用关键字Sub将其声明成过程。有的函数具有返回值,则必须用关键字Function将其声明成函数,并且在声明语句的最后要用AS关键字指明函数返回值的类型。
例如add.DLL在VB中就可以声明为: Declare Function ADD Lib "c:\add.dll" (ByVal X AS Integer, ByVal Y AS Integer, ByVal filein as string) AS Integer
通过此声明语句将函数ADD声明到VB中,便可直接调用。
动态调用详解:
首先调用API LoadLibaray 装载dll,然后调用API GetProcAddress 得到dll的对应方法的地址。因为vb不像其他的有函数指针,在vb中声明函数原形,怎样把得到的函数地址赋给这个原形有些麻烦。
解决办法1: Option Explicit '我们要调用没有声明的API(dll)的功能! Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long '释放LoadLibrary载入的动态链接库,非零表示成功,零表示失败。 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 '检索指定的动态链接库(DLL)中的输出库函数地址(超找函数入口地址),成功则返回值是DLL中的输出函数地址,失败返回值是NULL。 Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As Long '将消息信息传送给指定的窗口过程。 Private Sub Form_Load() Dim LibHand As Long '载入的dll句柄 LibHand = LoadLibrary("user32") '将user32载入到内存。 CallWindowProc GetProcAddress(LibHand, "SetWindowTextA"), Me.hWnd, CStr(Now), ByVal 0&, ByVal 0& '调用SetWindowTextA函数功能 FreeLibrary LibHand '释放映射库的地址 End Sub |
解决办法2: 下面是动态调用MessageBoxA的源代码,上面的步骤被封装到RunDll32函数中,可放到模块(CallAPIbyName.bas)中: Dim s1() As Byte, s2() As Byte Const hWnd = 0 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&) End Sub 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 hModule = LoadLibrary(ByVal LibFileName) '读取API库 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 RunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3) '执行Assembly Code部分 FreeLibrary hModule '释放空间 End Function |
解决办法3: 在VB中嵌入汇编实现。loadlibary取得DLL,GetProcAddress取得函数地址,用VB嵌入汇编的写法压所需参数,CallWindowProc调用GetProcAddress返回的地址。 |
【VB技巧】VB静态调用与动态调用dll详解的更多相关文章
- (笔记)Linux下的静态库和动态库使用详解
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比 ...
- 深入探讨Linux静态库与动态库的详解(转)
2.生成动态库并使用 linux下编译时通过 -shared 参数可以生成动态库(.so)文件,如下 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静 ...
- Android项目中JNI技术生成并调用.so动态库实现详解
生成 jni方式有两种:一种是通过SWIG从C++代码生成过度的java代码:另一种是通过javah的方式从java代码自动生成过度的C++代码.两种方式下的步骤流程正好相反. 第一种方式:由于需要配 ...
- JNI_Android项目中调用.so动态库实现详解
转自:http://www.yxkfw.com/?p=7223 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.java package com.wwj. ...
- JNI_Android项目中调用.so动态库实现详解【转】
转自 http://www.cnblogs.com/sevenyuan/p/4202759.html 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.ja ...
- JNI_Android 项目中调用.so动态库实现详解
转自:http://www.yxkfw.com/?p=7223 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.java package com.wwj. ...
- C++调用DLL有两种方法——静态调用和动态调用
C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报 分类: cpp(30) [ ...
- c/c++ 继承与多态 静态调用与动态调用
静态调用,与动态调用. 动态调用条件:必须用父类的引用或者指针,并且调用的必须是虚方法. #include <iostream> class Base{ public: virtual i ...
- dll静态调用和动态调用
动态链接库有2种连接方式,一种是通过库直接加入(又叫隐式加载或载入时加载),一种是在运行时加入.后者很好理解,比如LoadLibrary(),GetProcAddress()获取想要引入的函数,使用完 ...
随机推荐
- PHP Redis 普通封装类
class redisInit { private $redis; //redis对象 /** * 初始化Redis * $config = array( * 'server' => '127. ...
- C#获取一个文件的扩展名
C#获取一个文件的扩展名System.IO.Path.GetExtension( "文件名 ");ChangeExtension 更改路径字符串的扩展名. Combine ...
- C库函数手册(ctype.h)
ctype.h函数说明:int isalpha(int ch) 若ch是字母('A'-'Z','a'-'z')返回非0值,否则返回0 int isdigit(int ch) 若ch是数字('0'- ...
- Android加速度传感器实现“摇一摇”,带手机振动
由于代码有点多,所以就分开写了,注释还算详细,方便学习 Activity package com.lmw.android.test; import android.app.Activity; im ...
- Go Deeper(2010成都现场赛题)(2-sat)
G - Go Deeper Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Description ...
- Android软件开发需要学什么
首先,需要学习哪些Android开发技术? Android的开发技术很多,在开始学习的时候不可能一次性全部学会,也没有必要一开始都全部学会,但是有些技术是非常常用的,需要在开始时打好基础,这些技术时: ...
- UVa 10943 (数学 递推) How do you add?
将K个不超过N的非负整数加起来,使它们的和为N,一共有多少种方法. 设d(i, j)表示j个不超过i的非负整数之和为i的方法数. d(i, j) = sum{ d(k, j-1) | 0 ≤ k ≤ ...
- Linux“Bash”漏洞大爆发
9月25日,国外曝出一个“毁灭级”的Bash漏洞,黑客可利用此漏洞远程执行任意命令,完全控制目标系统! 该漏洞编号为CVE-2014-6271,主要存在于bash 1.14 - 4.3版本中,受影响的 ...
- IIS Server is too busy 解决方法(IIS6)
Server is too busy意思是服务器繁忙,资源不够用 为什么会出现这个问题呢? 因为服务器的配置不同,所能承受的压力不同. 而服务器默认对链接数,线程数等有设置,但这个设置太小,基本不够用 ...
- 入门视频采集与处理(学会分析YUV数据)
做视频采集与处理,自然少不了要学会分析YUV数据.因为从采集的角度来说,一般的视频采集芯片输出的码流一般都是YUV数据流的形式,而从视频处理(例如H.264.MPEG视频编解码)的角度来说,也是在原始 ...