一、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 : Attribute13 {14 // Summary:15 // Enables or disables best-fit mapping behavior when converting Unicode characters16 // 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 name25 // 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.CharSet34 // field causes the common language runtime to search an unmanaged DLL for entry-point35 // names other than the one specified.36 public bool ExactSpelling;37 //38 // Summary:39 // Indicates whether unmanaged methods that have HRESULT or retval return values40 // are directly translated or whether HRESULT or retval return values are automatically41 // converted to exceptions.42 public bool PreserveSig;43 //44 // Summary:45 // Indicates whether the callee calls the SetLastError Win32 API function before46 // returning from the attributed method.47 public bool SetLastError;48 //49 // Summary:50 // Enables or disables the throwing of an exception on an unmappable Unicode51 // 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.DllImportAttribute56 // 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 include61 // 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 BLApi2 {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, ListDependentDllPaths = 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 try11 {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 }