- 浏览: 176203 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
xiangyufangai:
很好很强大膜拜中哈哈!!
VB 两个字符串处理函数(类似Left/Mid/Right/Split的结合) -
hellohank:
这个……叫摘要算法,不叫加密算法~
Java实现的加密工具类(支持MD5和SHA) -
NIUCH1029291561:
接口有问题奥
网银在线支付接口和应用 -
yeuego:
能幫你就行了
MySQL索引分析 -
ForgiDaved:
很给力的介绍。记得前段时间给一个系统加功能,设计的表没有 ...
MySQL索引分析
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
'执行Assembly Code部分
RunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)
FreeLibrary hModule '释放空间
End Function
Private Function GetCodeStart(ByVal lngProc As Long, ByVal arrParams As Variant) As Long
'---以下为Assembly部分--
'作用:将函数的参数压入堆栈
Dim lngIndex As Long, lngCodeStart As Long
'程序起始位址必须是16的倍数
'VarPtr函数是用来取得变量的地址
lngCodeStart = (VarPtr(m_OpCode(0)) Or &HF) + 1
m_opIndex = lngCodeStart - VarPtr(m_OpCode(0)) '程序开始的元素的位置
'前面部分以中断点添满
For lngIndex = 0 To m_opIndex - 1
m_OpCode(lngIndex) = &HCC 'int 3
Next lngIndex
'--------以下开始放入所需的程序----------
'将参数push到堆栈
'由于是STDCall CALL 参数由最后一个开始放到堆栈
For lngIndex = UBound(arrParams) To 0 Step -1
AddByteToCode &H68 'push的机器码为H68
AddLongToCode CLng(arrParams(lngIndex)) '参数地址
Next lngIndex
'call hProc
AddByteToCode &HE8 'call的机器码为HE8
AddLongToCode lngProc - VarPtr(m_OpCode(m_opIndex)) - 4 '函数地址 用call的定址
'-----------结束所需的程序--------------
'返回呼叫函数
AddByteToCode &HC2 'ret 10h
AddByteToCode &H10
AddByteToCode &H0
GetCodeStart = lngCodeStart
End Function
Private Sub AddLongToCode(lData As Long)
'将Long类型的参数写到m_OpCode中
CopyMemory m_OpCode(m_opIndex), lData, 4
m_opIndex = m_opIndex + 4
End Sub
Private Sub AddIntToCode(iData As Byte)
'将Integer类型的参数写道m_OpCode中
CopyMemory m_OpCode(m_opIndex), iData, 2
m_opIndex = m_opIndex + 2
End Sub
Private Sub AddByteToCode(bData As Byte)
'将Byte类型的参数写道m_OpCode中
m_OpCode(m_opIndex) = bData
m_opIndex = m_opIndex + 1
End Sub
发表评论
-
vb 启动外部程序并且模拟鼠标点击
2011-03-09 13:28 1180Imports System.Runtime.InteropS ... -
VB 列出SQL数据库中所有表及字段信息
2011-03-09 13:24 1166程序思想:用Select name From sysobje ... -
VB 纯代码实现Timer控件的功能
2011-03-09 13:23 1376本博客有一篇类似的文章《VB 中运用 TimeSetEvent ... -
VB 控制音量
2011-03-09 13:22 1243'按钮一是音量增加,按钮二是音量减少,按钮三是静音切换. ... -
拦截 VB TextBox 双击消息
2011-03-09 13:22 955我们都知道在VB中TextBox默认是没有双击消息过程的(也就 ... -
VB 获取/设置屏幕分辨率
2011-03-09 13:21 1126Option ExplicitPrivate Decla ... -
VB 将数据快速导入EXCEL
2011-03-09 13:21 1048Public Function ToExcel()On ... -
VB 建立快捷方式
2011-03-09 13:20 791Private Declare Function fCr ... -
VB 获取快捷方式原文件路径
2011-03-09 13:20 933'此方法不需要引用IShellLink.Private ... -
VB 的一组字符串转换函数
2011-03-09 13:20 796Public Function chrConvert(s ... -
VB 在浏览目录时指定初始目录
2011-03-09 13:19 1084'VB也可以使用CallBack,下面是一个例子: '先 ... -
VB 获得鼠标滚轮的事件
2011-03-09 13:18 1007'窗体代码Private Sub Form_Load() ... -
VB 比较两组字符串
2011-03-09 13:18 1301【方法一】 StrComp(string1, Stri ... -
VB 用API下载文件实例
2011-03-09 13:17 807'########################### ... -
VB 窗口处理技巧大全
2011-03-09 13:17 794VB提供了API函数SetWindowLong和GetWind ... -
VB 实现屏幕右下角浮出式消息窗口,透明淡出效果。
2011-03-09 13:16 1006'任务栏高度[此部分相关代码转载自 枕善居]Privat ... -
VB Filter 函数用法
2011-03-09 13:16 1966例子1:Dim aa(10) As StringDim bbD ... -
VB 在EXPLORER进程崩溃之后重建托盘图标
2011-03-09 13:15 856重点为:向系统注册“TaskbarCreated”消息 ... -
Shell 调用程序后等待该程序结束后返回继续
2011-03-09 13:15 1236方法1: Private Declare Functi ... -
VB 最简单的WAV声音或音乐文件播放的代码
2011-03-09 13:14 1384'最简单的WAV声音或音乐文件播放的代码'API声明Pr ...
相关推荐
VB如何动态调用API的方法演示,最简单的调用API函数,动态调用API函数显示的MSGBOX内容,下面将要在作面画一笔。 函 数 名:ExecuteAPI 输入 :LIBPath(String) - 刷新的目标窗口句柄,可为0 APIScript...
如果结构体内的成员未按照4字节边界对齐,可能会导致VB调用时的数据读取错误。 ### 数据类型匹配 VB与C/C++的数据类型并不完全对应,尤其是在处理整型数据时。例如,C中的int类型在VB中应声明为long,而short类型...
2. **使用DLL函数**:一旦导入了DLL函数,就可以在VB.NET代码中像调用普通.NET方法一样调用它们。例如: ```vb.net Dim result As Integer = NativeMethods.MyFunction(10, 20) ``` 3. **处理错误**:由于C++和...
在VB(Visual Basic)编程环境中,我们可以利用API接口来调用外部服务,如百度地图,以便在应用程序中集成地图功能。这个"VB调用百度地图示例"是关于如何在VB程序中集成百度地图API,实现地图显示以及平移至特定坐标...
VB(Visual Basic)是Microsoft开发的一种面向对象的编程语言,它提供了丰富的功能来调用外部的DLL文件。在VB中调用C语言编写的DLL,可以实现VB无法原生支持的一些功能,如底层硬件操作或高性能计算。 首先,了解...
### QTP调用外部动态库的方法详解 #### 引言 在软件测试领域,自动化测试已成为提高测试效率和质量的关键手段。Mercury公司的QuickTest Professional(QTP),凭借其强大的功能和用户友好的界面,成为了自动化测试...
总之,VB通过Shell函数和`WScript.Shell`对象提供了一种灵活的方式来调用外部exe,并能等待其返回,从而实现更复杂的交互操作。掌握这种技术对于任何VB开发者来说都是非常有价值的,无论你是新手还是经验丰富的...
在.NET框架下,C#和VB.NET都是微软...以上就是关于"C#编写DLL让VB调用"的知识点,涵盖了创建C# DLL、接口设计、VB引用和调用DLL的方法。通过理解这些概念,开发者可以有效地在不同.NET语言之间实现代码共享和互操作。
本文将深入探讨VB调用VC动态连接库的关键知识点,包括其背景、步骤、注意事项以及实际应用中的优化策略。 ### 一、背景与意义 在早期的Windows应用程序开发中,Visual Basic以其易学易用的特点,吸引了大量开发者...
首先,VB调用VBS脚本的主要目的是利用VBS的灵活性和简洁性来执行一些特定任务,如系统管理、文件操作或自动化流程。VBS脚本易于编写,且支持Windows API调用,这使得它在系统级任务中非常实用。 **调用VBS脚本的...
在.NET框架中,VB.NET(Visual Basic .NET)是一种面向对象的编程语言,它提供了丰富的功能,包括调用外部DLL(动态链接库)文件。DLL是包含可重用代码的库,可以被多个应用程序共享,以减少内存占用和提高代码效率...
首先,VB6.0中的"Shell"函数是调用外部程序的关键。`Shell`函数允许我们启动一个操作系统外壳程序,例如浏览器。在VB6.0中,你可以使用以下代码来启动默认的浏览器并导航到特定的URL: ```vb Private Sub Command1_...
【VB调用 示例】是一个关于如何在Visual Basic (VB)环境中进行函数调用和程序交互的教程。VB是一种流行的编程语言,尤其适用于开发Windows应用程序。在这个示例中,我们可能会探讨如何利用VB来调用外部代码,如DLL...
**VB调用WINIO简介** 在Windows环境下,开发硬件接口程序时,我们常常需要与底层硬件进行直接交互,这时就涉及到了系统I/O操作。WINIO是一个常用的动态链接库(DLL),它允许开发者通过编程方式访问计算机的端口,...
2. **引用外部库**:另一种方法是通过引用外部DLL(动态链接库)文件,如提供的“panda.dll”。这通常意味着你正在使用一个已经封装好的键盘模拟库,比如AutoHotkey或PandaLibrary。这些库提供了更高级的接口,使VB...
在这个实例中,我们关注的是“VB调用TTS语音控件”,这是一个能够实现文本转语音(Text To Speech,简称TTS)功能的应用。TTS技术允许程序将文本数据转化为可听见的语音输出,这对于无障碍应用、教育软件、自动播报...
4. **错误处理**:由于调用外部组件可能存在失败的风险,因此应该添加适当的错误处理机制。例如,使用`On Error`语句来捕获和处理可能的异常。 5. **释放对象**:使用完组件后,别忘了释放对象以避免内存泄漏。这...
### 使用调用外部程序函数实现API函数高级功能 在计算机编程领域中,API(应用程序接口)是一组定义软件组件如何相互交互的规则。通过API,开发者可以利用预先编写好的功能代码,无需了解底层实现细节就能完成特定...
在VB6(Visual Basic 6)中调用百度地图小程序是一项技术性的工作,涉及到API接口的使用、网络请求以及数据解析等多个方面的知识。这个源代码应该是实现了一个接口,允许VB6程序与百度地图服务进行交互,例如获取...