zoukankan      html  css  js  c++  java
  • C#实现动态调用Windows DLL

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

    调用方法:

    object obj = WinDllInvoke("Kernel32.dll""Beep"new object[] { 750300 }, 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         /// <summary>
    11         /// 动态调用Windows DLL
    12         /// </summary>
    13         /// <param name="fileName">Dll文件名</param>
    14         /// <param name="funName">待调用的函数名</param>
    15         /// <param name="objParams">函数参数</param>
    16         /// <param name="returnType">返回值</param>
    17         /// <returns>调用结果</returns>
    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         }
  • 相关阅读:
    MySQL 有关权限的表都有哪几个?
    MyISAM 表格将在哪里存储,并且还提供其存储格式?
    你是怎么看Spring框架的?
    elasticsearch 的倒排索引是什么 ?
    主键和候选键有什么区别?
    MySQL 支持事务吗?
    可以使用多少列创建索引?
    LIKE 声明中的%和_是什么意思?
    什么是通用 SQL 函数?
    MySQL 中有哪些不同的表格?
  • 原文地址:https://www.cnblogs.com/mondol/p/1401041.html
Copyright © 2011-2022 走看看