一、DllImportAttribute
1、属性介绍
1 using System; 2 using System.Reflection; 3 using System.Security; 4 5 namespace System.Runtime.InteropServices 6 { 7 // Summary: 8 // Indicates that the attributed method is exposed by an unmanaged dynamic-link 9 // library (DLL) as a static entry point. 10 [AttributeUsage(AttributeTargets.Method, Inherited = false)] 11 [ComVisible(true)] 12 public sealed class DllImportAttribute : Attribute 13 { 14 // Summary: 15 // Enables or disables best-fit mapping behavior when converting Unicode characters 16 // to ANSI characters. 17 public bool BestFitMapping; 18 // 19 // Summary: 20 // Indicates the calling convention of an entry point. 21 public CallingConvention CallingConvention; 22 // 23 // Summary: 24 // Indicates how to marshal string parameters to the method and controls name 25 // mangling. 26 public CharSet CharSet; 27 // 28 // Summary: 29 // Indicates the name or ordinal of the DLL entry point to be called. 30 public string EntryPoint; 31 // 32 // Summary: 33 // Controls whether the System.Runtime.InteropServices.DllImportAttribute.CharSet 34 // field causes the common language runtime to search an unmanaged DLL for entry-point 35 // names other than the one specified. 36 public bool ExactSpelling; 37 // 38 // Summary: 39 // Indicates whether unmanaged methods that have HRESULT or retval return values 40 // are directly translated or whether HRESULT or retval return values are automatically 41 // converted to exceptions. 42 public bool PreserveSig; 43 // 44 // Summary: 45 // Indicates whether the callee calls the SetLastError Win32 API function before 46 // returning from the attributed method. 47 public bool SetLastError; 48 // 49 // Summary: 50 // Enables or disables the throwing of an exception on an unmappable Unicode 51 // character that is converted to an ANSI "?" character. 52 public bool ThrowOnUnmappableChar; 53 54 // Summary: 55 // Initializes a new instance of the System.Runtime.InteropServices.DllImportAttribute 56 // class with the name of the DLL containing the method to import. 57 // 58 // Parameters: 59 // dllName: 60 // The name of the DLL that contains the unmanaged method. This can include 61 // an assembly display name, if the DLL is included in an assembly. 62 public DllImportAttribute(string dllName); 63 64 // Summary: 65 // Gets the name of the DLL file that contains the entry point. 66 // 67 // Returns: 68 // The name of the DLL file that contains the entry point. 69 public string Value { get; } 70 } 71 }
2、举例
1 class BLApi 2 { 3 [DllImport(@"xx.dll", EntryPoint = "TWelcomeFace_Init", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] 4 public extern static Int32 TWelcomeFace_Init(string namingService, string localhost, string dvsService, string matchService); 5 }
3、引入依赖dll
将依赖dll添加到解决方案中,与主dll放在相同目录下(重要),然后设置dll的属性CopyToOutputDirectory= CopyAlways,编译器就会自动找到了。
二、应用LoadLibrary
1、封装基础类
1 public class DllInvoke 2 { 3 [DllImport("kernel32.dll")] 4 private extern static IntPtr LoadLibrary(String path); 5 [DllImport("kernel32.dll")] 6 private extern static IntPtr GetProcAddress(IntPtr lib, String funcName); 7 [DllImport("kernel32.dll")] 8 private extern static bool FreeLibrary(IntPtr lib); 9 [DllImport("kernel32.dll")] 10 private extern static int GetLastError(); 11 private IntPtr hLib; 12 public DllInvoke(String dllPath, List<string> DependentDllPaths = null) 13 { 14 if(DependentDllPaths != null) 15 { 16 foreach (string dllName in DependentDllPaths) 17 { 18 IntPtr loadAuxiliary = LoadLibrary(dllName); 19 if (loadAuxiliary == IntPtr.Zero) 20 { 21 throw new Exception(dllName + "加载失败!"); 22 } 23 } 24 } 25 hLib = LoadLibrary(dllPath); 26 } 27 ~DllInvoke() 28 { 29 FreeLibrary(hLib); 30 } 31 32 public Delegate Invoke(String APIName, Type t) 33 { 34 IntPtr api = GetProcAddress(hLib, APIName); 35 var s = Marshal.GetDelegateForFunctionPointer(api, t); 36 return (Delegate)s; 37 } 38 }
LoadLibrary引用的dll相关的依赖dll必须被手动引用进来,否则会报错。
2、举例
1 [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true)] 2 delegate Int32 TWelcomeFace_Init(string Naming_Service, string Locale_Host, string DVS_Service, string Match_Service); 3 4 class BLApi 5 { 6 private static DllInvoke _dll = new DllInvoke(@"xx.dll"); 7 8 public static Int32 TWelcomeFace_Init(string namingService, string localhost, string dvsService, string matchService) 9 { 10 try 11 { 12 TWelcomeFace_Init dele = (TWelcomeFace_Init)_dll.Invoke("TWelcomeFace_Init", typeof(TWelcomeFace_Init)); 13 Int32 result = dele(namingService, localhost, dvsService, matchService); 14 15 return result; 16 } 17 catch (Exception ex) 18 { 19 throw ex; 20 } 21 } 22 }