C#实现动态调用Windows DLL

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

调用方法:

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          }

你可能感兴趣的:(C#实现动态调用Windows DLL)