C#实现动态调用Windows DLL (转载自中国IT实验室)

部分代码来自于网络;废话不多说,上代码:

调用方法:

object obj = WinDllInvoke("Kernel32.dll", "Beep", new object[] { 750, 300 }, typeof(void));
函数代码:


 1 [System.Runtime.InteropServices.DllImport("kernel32")]
 2          private static extern IntPtr LoadLibrary(string lpLibFileName);
 3  
 4          [System.Runtime.InteropServices.DllImport("kernel32")]
 5          private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
 6  
 7          [System.Runtime.InteropServices.DllImport("kernel32")]
 8          private static extern IntPtr FreeLibrary(IntPtr hLibModule);
 9 
10        /// 
11         /// 动态调用Windows DLL
12         /// 
13         /// Dll文件名
14         /// 待调用的函数名
15         /// 函数参数
16        /// 返回值
17         /// 调用结果

18         private static object WinDllInvoke(string fileName, string funName, object[] objParams, Type returnType)
19         {
20             IntPtr libHandle = IntPtr.Zero;
21 
22             try             {                 //获取函数地址
23                libHandle = LoadLibrary(fileName);
24                if (libHandle == IntPtr.Zero) return null;
25                 IntPtr procAddres = GetProcAddress(libHandle, funName);
26                if (procAddres == IntPtr.Zero) return null;
27                 
28                 //获取参数类型
29                Type[] paramTypes = new Type[objParams.Length];
30                 for (int i = 0; i < objParams.Length; ++i)
31                {
32                     paramTypes[i] = objParams[i].GetType();
33                 }

34 
35                //构建调用方法模型
36                 AssemblyName asembyName = new AssemblyName();
37                 asembyName.Name = "WinDllInvoke_Assembly";
38                AssemblyBuilder asembyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asembyName, AssemblyBuilderAccess.Run);
39                 ModuleBuilder moduleBuilder = asembyBuilder.DefineDynamicModule("WinDllInvoke");                 MethodBuilder methodBuilder = moduleBuilder.DefineGlobalMethod("InvokeFun", MethodAttributes.Public | MethodAttributes.Static, returnType, paramTypes);
40
41                //获取一个 ILGenerator ,用于发送所需的 IL 
42                 ILGenerator IL = methodBuilder.GetILGenerator();
43                 for (int j = 0; j < paramTypes.Length; ++j)
44                 {
45                     //将参数压入堆栈
46                     if (paramTypes[j].IsValueType)
47                    {
48                        IL.Emit(OpCodes.Ldarg, j); //By Value
49                     }

50                     else
51                   {
52                         IL.Emit(OpCodes.Ldarga, j); //By Addrsss
53                     }

54                 }

55
56               // 判断处理器类型
57                if (IntPtr.Size == 4)
58                 {
59                    IL.Emit(OpCodes.Ldc_I4, procAddres.ToInt32());
60                 }

61                else if (IntPtr.Size == 8)
62                {
63                    IL.Emit(OpCodes.Ldc_I8, procAddres.ToInt64());
64                }

65                 else
66               {
67                    throw new PlatformNotSupportedException("不好意思,偶不认得你哦!");
68}

69 IL.EmitCalli(OpCodes.Calli,CallingConvention.StdCall, returnType, paramTypes);
70               IL.Emit(OpCodes.Ret); // 返回值 
71               moduleBuilder.CreateGlobalFunctions(); 
72                // 取得方法信息 
73  MethodInfo methodInfo=moduleBuilder.GetMethod("InvokeFun");
74
75                return methodInfo.Invoke(null, objParams);// 调用方法,并返回其值
76             }

77             catch return null; }
78             finally
79             {
80                 if (libHandle != IntPtr.Zero) FreeLibrary(libHandle); //释放资源
81             }

82         }

83
84

 

posted @ 2009-08-13 15:23  Ants  阅读(289)  评论(0编辑  收藏  举报