background image

FARPROC   GetProcAddress(HMODULE   hModule,   LPCWSTR   lpProcName);   BOOL 
FreeLibrary(HMODULE hModule);
现 在 , 我 们 可 以 用 IntPtr hModule=LoadLibrary(“Count.dll”);来 获 得 Dll 的 句 柄 ,用 IntPtr 
farProc=GetProcAddress(hModule,”_count@4”);

 

来获得函数的入口地址。 但是,知道函数的

入口地址后,怎样调用这个函数呢?因为在 C#中是没有函数指针的,没有像 C++那样的
函数指针调用方式来调用函数,所以我们得借助其它方法。经过研究,发现我们可以通过
结合使用 System.Reflection.Emit 及 System.Reflection.Assembly 里的类和函数达到我们的目

 

的。为了以后使用方便及实现代码的复用,我们可以编写一个类。 1) dld 类的编写:
1. 

打开项目 Tzb”

,打开类视图,右击 Tzb”

,选择 添加 -->“ ”

类 ,类名设置为 dld”,即

dynamic loading dll 的每个单词的开头字母。
2. 添加所需的命名空间及声明参数传递方式枚举:
using   System.Runtime.InteropServices;   //  

 

用 DllImport  

 

 

需 用 此 命 名 空 间

using 

System.Reflection; // 

 

使用 Assembly 

 

 

类需用此 命名空间 using System.Reflection.Emit; // 使用 

ILGenerator 

 

需用此 命名空间

在 public class dld”

 

上面添加如下代码声明参数传递方式枚举: /// <summary>

/// 

 

参数传递方式枚举 ,ByValue 

 

表示值传递 ,ByRef 

 

表示址传递 /// </summary> public enum 

ModePass {
ByValue = 0x0001, ByRef = 0x0002 }
3.   声 明 LoadLibrary 、GetProcAddress 、 FreeLibrary 及 私有 变量 hModule 和 farProc

 

: /// 

<summary>
/// 

 

原型是 :HMODULE LoadLibrary(LPCTSTR lpFileName); /// </summary>

/// <param name="lpFileName">DLL  

 

文 件 名 </param> /// <returns>   函 数 库 模 块 的 句 柄 

</returns> [DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName); /// <summary>
///  

 

原 型 是 : FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName); /// 

</summary>
/// <param name="hModule"> 

 

包含需调用函数的函数库模块的句柄 </param> /// <param 

name="lpProcName"> 

 

调用函数的名称 </param> /// <returns> 

 

函数指针 </returns>

[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); /// <summary>
/// 

 

原型是 : BOOL FreeLibrary(HMODULE hModule); /// </summary>

/// <param name="hModule"> 

 

需释放的函数库模块的句柄 </param> /// <returns> 是否已释放

 

指定的 Dll</returns>
[DllImport("kernel32",EntryPoint="FreeLibrary",SetLastError=true)]   static   extern   bool 
FreeLibrary(IntPtr hModule); /// <summary>
/// Loadlibrary 

 

返回的函数库模块的句柄 /// </summary>

private IntPtr hModule=IntPtr.Zero; /// <summary>
/// GetProcAddress 

 

返回的函数指针 /// </summary>

private IntPtr farProc=IntPtr.Zero;
4. 添加 LoadDll 方法,并为了调用时方便,重载了这个方法:
/// <summary> /// 

 

装载 Dll /// </summary>

/// <param name="lpFileName">DLL 

 

文件名 </param> public void LoadDll(string lpFileName)

{
hModule=LoadLibrary(lpFileName); if(hModule==IntPtr.Zero)