程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#實現動態調用Windows DLL

C#實現動態調用Windows DLL

編輯:關於C#

調用方法:

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             {
24                 //獲取函數地址
25                 libHandle = LoadLibrary(fileName);
26                 if (libHandle == IntPtr.Zero) return null;
27                 IntPtr procAddres = GetProcAddress(libHandle, funName);
28                 if (procAddres == IntPtr.Zero) return null;
29                
30                 //獲取參數類型
31                 Type[] paramTypes = new Type[objParams.Length];
32                 for (int i = 0; i < objParams.Length; ++i)
33                 {
34                     paramTypes[i] = objParams[i].GetType();
35                 }
36
37                 //構建調用方法模型
38                 AssemblyName asembyName = new AssemblyName();
39                 asembyName.Name = "WinDllInvoke_Assembly";
40                 AssemblyBuilder asembyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asembyName, AssemblyBuilderAccess.Run);
41                 ModuleBuilder moduleBuilder = asembyBuilder.DefineDynamicModule("WinDllInvoke");
42                 MethodBuilder methodBuilder = moduleBuilder.DefineGlobalMethod("InvokeFun", MethodAttributes.Public | MethodAttributes.Static, returnType, paramTypes);
43
44                 //獲取一個 ILGenerator ,用於發送所需的 IL
45                 ILGenerator IL = methodBuilder.GetILGenerator();
46                 for (int j = 0; j < paramTypes.Length; ++j)
47                 {
48                     //將參數壓入堆棧
49                     if (paramTypes[j].IsValueType)
50                     {
51                         IL.Emit(OpCodes.Ldarg, j); //By Value
52                     }
53                     else
54                     {
55                         IL.Emit(OpCodes.Ldarga, j); //By Addrsss
56                     }
57                 }
58
59                 // 判斷處理器類型
60                 if (IntPtr.Size == 4)
61                 {
62                     IL.Emit(OpCodes.Ldc_I4, procAddres.ToInt32());
63                 }
64                 else if (IntPtr.Size == 8)
65                 {
66                     IL.Emit(OpCodes.Ldc_I8, procAddres.ToInt64());
67                 }
68                 else
69                 {
70                     throw new PlatformNotSupportedException("不好意思,偶不認得你哦!");
71                 }
72
73                 IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, returnType, paramTypes);
74                 IL.Emit(OpCodes.Ret); // 返回值
75                 moduleBuilder.CreateGlobalFunctions();
76
77                 // 取得方法信息
78                 MethodInfo methodInfo = moduleBuilder.GetMethod("InvokeFun");
79
80                 return methodInfo.Invoke(null, objParams);// 調用方法,並返回其值
81             }
82             catch { return null; }
83             finally
84             {
85                 if (libHandle != IntPtr.Zero) FreeLibrary(libHandle); //釋放資源
86             }
87         }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved