一个动态调用DLL的源码

翻译 2007年10月02日 15:39:00
Option Explicit

Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Public Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Public 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
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Private m_opIndex As Long '写入位置
Private m_OpCode() As Byte  'Assembly 的OPCODE

Public Function DynamicRunDll32(ByVal isUnload As Boolean, ByVal strLibFileName As String, strProcName 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 strLibFileName)
    If hModule = 0 Then
        MsgBox "Library读取失败!"
        DynamicRunDll32 = 0
        Exit Function
    End If
   
    '取得函数地址
    hProc = GetProcAddress(hModule, ByVal strProcName)
    If hProc = 0 Then
       MsgBox "函数读取失败!", vbCritical
       FreeLibrary hModule
       DynamicRunDll32 = 0
       Exit Function
    End If
    '执行Assembly Code部分
    DynamicRunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)
    '一些函数需要驻留这就先不释放
    If isUnload Then FreeLibrary hModule  '释放空间
End Function

'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


窗体源码:

Private Sub cmdOk_Click()
    Call DynamicRunDll32(False, "test.dll", "ShowMessage")
End Sub

Private Sub Form_Load()
   Dim s1() As Byte, s2() As Byte
   Dim ret As Long
   s1 = StrConv("123", vbFromUnicode)
   s2 = StrConv("VBNote", vbFromUnicode)
   ret = DynamicRunDll32(True, "user32", "SetWindowTextA", hWnd, VarPtr(s1(0)))
   ret = DynamicRunDll32(True, "user32", "SetWindowTextA", hWnd, StrPtr(s2))
   Call DynamicRunDll32(True, "kernel32", "DeleteFileA", StrPtr(StrConv("c:/111.txt", vbFromUnicode)))
End Sub 

动态调用有源码的DLL中的导出类

前言 动态调用DLL的好处: * 防止静态调用DLL不在报错 * 实现插件化编程 有源码的DLL可以添加接口 可以在DLL中加入建立类指针和释放类指针的接口, 不用自己去调用类构造和析构函数 ...
  • LostSpeed
  • LostSpeed
  • 2016年03月11日 00:14
  • 862

DLL的类库怎样实现动态加载调用

动态加载动态连接库能更加有效地使用内存,这在大型项目中是非常有用的一项技术。DLL中的函数可以很容易的实现动态加载调用,网上也有很多相关的介绍,但DLL中类库怎样实现动态加载调用呢?这是我在实际项目中...
  • caih2000
  • caih2000
  • 2007年01月20日 17:49
  • 2274

C#动态调用C++DLL

1.DLL中函数实现extern "C" __declspec(dllexport) int MultiplyByTen(int numberToMultiply);extrn "C" _declsp...
  • procedurecode
  • procedurecode
  • 2008年04月02日 12:41
  • 7619

C++全局函数的dll,C++动态调用。

1、项目结构 其实很简单,只要将CDLL.c文件的后缀改为.cpp即可。 2、 CDLL.h内容:#ifndef __CDLL_H__ #define __CDLL_H__ extern "...
  • wodownload2
  • wodownload2
  • 2016年12月15日 10:08
  • 326

dll动态调用和静态调用有什么区别

2010-06-14 22:1 一).静态调用其步骤如下: 1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下; 2.把你的youA...
  • chenchong_219
  • chenchong_219
  • 2013年04月12日 22:58
  • 596

delphi dll 静态调用和动态调用方法总结

dll 调用方法有 静态调用和动态调用两种方法用到的dll为上篇文章所编写的dll.总结如下: Unit Unit1;InterfaceUses  Windows, Messages, SysUtil...
  • fkedwgwy
  • fkedwgwy
  • 2010年01月09日 12:40
  • 3597

利用反射进行动态加载dll

/// /// 短信发送接口实现工厂 /// public static class EosSMSProviderFactory { public ...
  • xiaoqiaoluanwu
  • xiaoqiaoluanwu
  • 2016年11月23日 14:24
  • 287

DLL静态和动态调用

采用lib文件调用DLL(采用Lib文件的调用方式又被称为静态调用) 静态调用定义: 静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责...
  • Sya_inn
  • Sya_inn
  • 2017年01月02日 19:15
  • 434

非常不错的C#动态调用DLL代码

一、新建一调用工程项目和一个要测试的类项目,首先设计好测试的类以及函数,然后编译生成对应的类名.DLL文件。然后复制到调用工程项目的BIN目录下。   二、在调用工程项目中新建一WINFORM窗体...
  • xqf222
  • xqf222
  • 2012年09月15日 23:49
  • 2604

通过函数指针动态调用 dll 中的函数

/******************************************************************////name       : GetKey//function...
  • hzhxxx
  • hzhxxx
  • 2006年06月22日 12:48
  • 1405
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个动态调用DLL的源码
举报原因:
原因补充:

(最多只允许输入30个字)