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
原创文字只代表本人某一时间内的观点或结论,本人不对涉及到的任何代码担保。转载请标明出处!