分类:
2010-12-02 09:41:09
5.
添加LoadFun方法,并为了调用时方便,也重载了这个方法,方法的具体代码及注释如下:
/// /// 获得函数指针 /// /// 调用函数的名称 public void LoadFun(string lpProcName) { // 若函数库模块的句柄为空,则抛出异常 if(hModule==IntPtr.Zero) throw(new Exception(" 函数库模块的句柄为空 , 请确保已进行 LoadDll 操作 !")); // 取得函数指针 farProc = GetProcAddress(hModule,lpProcName); // 若函数指针,则抛出异常 if(farProc==IntPtr.Zero) throw(new Exception(" 没有找到 :"+lpProcName+" 这个函数的入口点 ")); } /// /// 获得函数指针 /// /// 包含需调用函数的 DLL 文件名 /// 调用函数的名称 public void LoadFun(string lpFileName,string
lpProcName) { // 取得函数库模块的句柄 hModule=LoadLibrary(lpFileName); // 若函数库模块的句柄为空,则抛出异常 if(hModule==IntPtr.Zero) throw(new Exception(" 没有找到 :"+lpFileName+"." )); // 取得函数指针 farProc = GetProcAddress(hModule,lpProcName); // 若函数指针,则抛出异常 if(farProc==IntPtr.Zero) throw(new Exception(" 没有找到 :"+lpProcName+" 这个函数的入口点 ")); } |
6.
添加UnLoadDll及Invoke方法,Invoke方法也进行了重载:
/// /// 卸载 Dll /// public void UnLoadDll() { FreeLibrary(hModule); hModule=IntPtr.Zero; farProc=IntPtr.Zero; } |
Invoke方法的第一个版本:
/// /// 调用所设定的函数 /// /// 实参 ///
实参类型 /// 实参传送方式 /// 返回类型 /// public object Invoke(object[]
ObjArray_Parameter,Type[] TypeArray_ParameterType,ModePass[]
ModePassArray_Parameter,Type Type_Return) { // 下面 3 个 if 是进行安全检查 , 若不能通过 , 则抛出异常 if(hModule==IntPtr.Zero) throw(new Exception(" 函数库模块的句柄为空 , 请确保已进行 LoadDll 操作 !")); if(farProc==IntPtr.Zero) throw(new Exception(" 函数指针为空 , 请确保已进行 LoadFun 操作 !" ) ); if(ObjArray_Parameter.Length!=ModePassArray_Parameter.Length)
throw(new Exception(" 参数个数及其传递方式的个数不匹配 ." ) ); // 下面是创建
MyAssemblyName 对象并设置其 Name 属性 AssemblyName MyAssemblyName = new AssemblyName(); MyAssemblyName.Name = "InvokeFun"; // 生成单模块配件 AssemblyBuilder MyAssemblyBuilder
=AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName,AssemblyBuilderAccess.Run);
ModuleBuilder MyModuleBuilder
=MyAssemblyBuilder.DefineDynamicModule("InvokeDll"); // 定义要调用的方法 , 方法名为“ MyFun ”,返回类型是“ Type_Return ”参数类型是“ TypeArray_ParameterType ” MethodBuilder MyMethodBuilder
=MyModuleBuilder.DefineGlobalMethod("MyFun",MethodAttributes.Public|
MethodAttributes.Static,Type_Return,TypeArray_ParameterType); // 获取一个
ILGenerator ,用于发送所需的 IL int i; for (i = 0; i < ObjArray_Parameter.Length; i++) {// 用循环将参数依次压入堆栈 switch (ModePassArray_Parameter[i]) { case ModePass.ByValue: IL.Emit(OpCodes.Ldarg, i); break; case ModePass.ByRef: IL.Emit(OpCodes.Ldarga, i); break; default: throw(new Exception(" 第 " +(i+1).ToString() + " 个参数没有给定正确的传递方式 ." ) ); } } if (IntPtr.Size == 4) {// 判断处理器类型 IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32()); } else if (IntPtr.Size == 8) { IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64()); } else { throw new PlatformNotSupportedException(); } IL.EmitCalli(OpCodes.Calli,CallingConvention.StdCall,Type_Return,TypeArray_ParameterType);
IL.Emit(OpCodes.Ret); // 返回值 MyModuleBuilder.CreateGlobalFunctions(); // 取得方法信息 MethodInfo MyMethodInfo = MyModuleBuilder.GetMethod("MyFun");
return MyMethodInfo.Invoke(null,
ObjArray_Parameter);// 调用方法,并返回其值 } |
Invoke方法的第二个版本,它是调用了第一个版本的:
/// /// 调用所设定的函数 /// /// 函数指针 ///
实参 /// 实参类型 /// 实参传送方式 /// 返回类型 /// public object Invoke(IntPtr IntPtr_Function,object[]
ObjArray_Parameter,Type[] TypeArray_ParameterType,ModePass[]
ModePassArray_Parameter,Type Type_Return) { // 下面 2 个 if 是进行安全检查 , 若不能通过 , 则抛出异常 if(hModule==IntPtr.Zero) throw(new Exception(" 函数库模块的句柄为空 , 请确保已进行 LoadDll 操作 !")); if(IntPtr_Function==IntPtr.Zero) throw(new Exception(" 函数指针 IntPtr_Function 为空 !" ) ); farProc=IntPtr_Function; return
Invoke(ObjArray_Parameter,TypeArray_ParameterType,ModePassArray_Parameter,Type_Return);
} |