乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C#總結(jié)(七)動(dòng)態(tài)加載C++動(dòng)態(tài)鏈接庫(kù)

       羊玉wngbx 2019-07-17

      C#調(diào)用C++ 鏈接庫(kù)的方式分為靜態(tài)調(diào)用和動(dòng)態(tài)調(diào)用這兩種方式。靜態(tài)調(diào)用之前的文章里面都有介紹,使用.net 提供的DllImport 導(dǎo)入相關(guān)的C++ 庫(kù)即可。請(qǐng)看之前的文章,https://www.cnblogs.com/zhangweizhong/p/8119340.html 。


      今天介紹動(dòng)態(tài)調(diào)用的方法。很多時(shí)候,Dll庫(kù)的目錄可能是變化的,或是有些場(chǎng)景,需要根據(jù)具體的情況,來(lái)動(dòng)態(tài)加載這些Dll庫(kù)。這樣使用靜態(tài)調(diào)用的方式就很不方便,C#中我們經(jīng)常通過(guò)配置動(dòng)態(tài)的調(diào)用托管Dll,那么是不是也可以這樣動(dòng)態(tài)調(diào)用C++動(dòng)態(tài)鏈接呢?
      只要通過(guò)LoadLibrary, GetProcess, FreeLibrary這幾個(gè)函數(shù)是可以動(dòng)態(tài)調(diào)用動(dòng)態(tài)鏈接的(它們包含在kernel32.dll中)。

       

      原理

      LoadLibrary ( string lpFileName):載入指定的動(dòng)態(tài)鏈接庫(kù),并將它映射到當(dāng)前進(jìn)程使用的地址空間。載入成功后即可訪問(wèn)庫(kù)內(nèi)保存的資源 , 除了LoadLibrary 方法,還有一個(gè)類(lèi)似的 LoadLibraryEx 方法。

      GetProcAddress (int hModule, string lpProcName):GetProcAddress函數(shù)檢索指定的動(dòng)態(tài)鏈接庫(kù)(DLL)中的輸出庫(kù)函數(shù)地址。 如果函數(shù)調(diào)用成功,返回值是DLL中的輸出函數(shù)地址。 如果函數(shù)調(diào)用失敗,返回值是NULL。調(diào)用函數(shù)GetLastError ,得到具體的錯(cuò)誤信息。

       

      FreeLibrary ( int hModule)  :釋放指定的動(dòng)態(tài)鏈接庫(kù),它們?cè)缦仁怯肔oadLibrary API函數(shù)裝載的。

       

      GetLastError() : 獲取錯(cuò)誤信息

       

      實(shí)現(xiàn)

       

      1. 將kernel32中的幾個(gè)方法封裝成本地調(diào)用類(lèi) DLLWrapper

      復(fù)制代碼
      using System;
      using System.IO;
      using System.Runtime.InteropServices;
      
      namespace Irisking.Basic.Util
      {
          /// <summary>
          /// DLLWrapper
          /// </summary>
          internal class DLLWrapper
          {
              [DllImport("kernel32.dll")]
              private static extern uint GetLastError();
      
      
              /// <summary>
              /// API LoadLibraryEx
              /// </summary>
              /// <param name="lpFileName"></param>
              /// <param name="hReservedNull"></param>
              /// <param name="dwFlags"></param>
              /// <returns></returns>
              [DllImport("kernel32.dll", EntryPoint = "LoadLibraryEx", SetLastError = true)]
              private static extern int LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
      
              /// <summary>
              /// API GetProcAddress
              /// </summary>
              /// <param name="handle"></param>
              /// <param name="funcname"></param>
              /// <returns></returns>
              [DllImport("Kernel32", EntryPoint = "GetProcAddress", SetLastError = true)]
              public static extern int GetProcAddress(int handle, string funcname);
      
              /// <summary>
              ///  API FreeLibrary
              /// </summary>
              /// <param name="handle"></param>
              /// <returns></returns>
              [DllImport("Kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]
              private static extern int FreeLibrary(int handle);
      
              ///<summary>
              /// 通過(guò)非托管函數(shù)名轉(zhuǎn)換為對(duì)應(yīng)的委托 , by jingzhongrong
              ///</summary>
              ///<param name="dllModule"> 通過(guò) LoadLibrary 獲得的 DLL 句柄 </param>
              ///<param name="functionName"> 非托管函數(shù)名 </param>
              ///<param name="t"> 對(duì)應(yīng)的委托類(lèi)型 </param>
              ///<returns> 委托實(shí)例,可強(qiáng)制轉(zhuǎn)換為適當(dāng)?shù)奈蓄?lèi)型 </returns>
              public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
              {
                  int address = GetProcAddress(dllModule, functionName);
                  if (address == 0)
                      return null;
                  else
                      return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
              }
      
              ///<summary>
              /// 將表示函數(shù)地址的 intPtr 實(shí)例轉(zhuǎn)換成對(duì)應(yīng)的委托
              ///</summary>
              public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
              {
                  if (address == IntPtr.Zero)
                      return null;
                  else
                      return Marshal.GetDelegateForFunctionPointer(address, t);
              }
      
              ///<summary>
              /// 將表示函數(shù)地址的 int  轉(zhuǎn)換成對(duì)應(yīng)的委托
              ///</summary>
              public static Delegate GetDelegateFromIntPtr(int address, Type t)
              {
                  if (address == 0)
                      return null;
                  else
                      return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
              }
      
              /// <summary>
              /// 加載sdk
              /// </summary>
              /// <param name="lpFileName"></param>
              /// <returns></returns>
              public static int LoadSDK(string lpFileName)
              {
                  if (File.Exists(lpFileName))
                  {
                      var hReservedNull = IntPtr.Zero;
                      var dwFlags = LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH;
      
                      var result = LoadLibraryEx(lpFileName, hReservedNull, dwFlags);
      
                      var errCode = GetLastError();
                      LogHelper.Info($"LoadSDK Result:{result}, ErrorCode: {errCode}");
                     
                      return result;
                  }
                  return 0;
              }
      
              /// <summary>
              /// 釋放sdk
              /// </summary>
              /// <param name="handle"></param>
              /// <returns></returns>
              public static int ReleaseSDK(int handle)
              {
                  try
                  {
                      if (handle > 0)
                      {
                          LogHelper.Info($"FreeLibrary handle:{handle}");
                          var result = FreeLibrary(handle);
                          var errCode = GetLastError();
                          LogHelper.Info($"FreeLibrary Result:{result}, ErrorCode: {errCode}");
                          return 0;
                      }
                      return -1;
                  }
                  catch (Exception ex)
                  {
                      LogHelper.Error(ex);
                      return -1;
                  }
              }
          }
      
          /// <summary>
          /// LoadLibraryFlags
          /// </summary>
          public enum LoadLibraryFlags : uint
          {
              /// <summary>
              /// DONT_RESOLVE_DLL_REFERENCES
              /// </summary>
              DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
      
              /// <summary>
              /// LOAD_IGNORE_CODE_AUTHZ_LEVEL
              /// </summary>
              LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
      
              /// <summary>
              /// LOAD_LIBRARY_AS_DATAFILE
              /// </summary>
              LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
      
              /// <summary>
              /// LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
              /// </summary>
              LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
      
              /// <summary>
              /// LOAD_LIBRARY_AS_IMAGE_RESOURCE
              /// </summary>
              LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
      
              /// <summary>
              /// LOAD_LIBRARY_SEARCH_APPLICATION_DIR
              /// </summary>
              LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200,
      
              /// <summary>
              /// LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
              /// </summary>
              LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000,
      
              /// <summary>
              /// LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
              /// </summary>
              LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,
      
              /// <summary>
              /// LOAD_LIBRARY_SEARCH_SYSTEM32
              /// </summary>
              LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,
      
              /// <summary>
              /// LOAD_LIBRARY_SEARCH_USER_DIRS
              /// </summary>
              LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400,
      
              /// <summary>
              /// LOAD_WITH_ALTERED_SEARCH_PATH
              /// </summary>
              LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
          }
      }
      復(fù)制代碼

       

      2. 使用DLLWrapper類(lèi)動(dòng)態(tài)讀取C++Dll,獲得函數(shù)指針,并且將指針?lè)庋b成C#中的委托。原因很簡(jiǎn)單,C#中已經(jīng)不能使用指針了,如下:

      定義委托

      UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
      public delegate int Delegate_IKUSBSDK_GetVersion([In] [Out] [MarshalAs(UnmanagedType.LPArray)] byte[] version);

       

       

      3. 調(diào)用函數(shù)

      復(fù)制代碼
      //1. 加載sdk
      var sdkModule = DLLWrapper.LoadSDK(_route.DeviceA_PATH);
      
      // 2. 通過(guò)handle 找到相關(guān)的函數(shù)
      Delegate_IKUSBSDK_GetVersion getVersion = (Delegate_IKUSBSDK_GetVersion)DLLWrapper.GetFunctionAddress(sdkModule, "IKUSBSDK_GetVersion", typeof(Delegate_IKUSBSDK_GetVersion));
      
      var result = getVersion(version);
      復(fù)制代碼

       

       

      最后

      通過(guò)如上例子,我們可以在C#中動(dòng)態(tài)或者靜態(tài)的調(diào)用C++寫(xiě)的代碼了。

       

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多