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 DLL12
/// 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 Value49
}50
else51
{52
IL.Emit(OpCodes.Ldarga, j); //By Addrsss53
}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
else66
{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
finally79
{80
if (libHandle != IntPtr.Zero) FreeLibrary(libHandle); //释放资源81
}82
}83

84

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


浙公网安备 33010602011771号