簡體   English   中英

使用DllImport將非托管dll加載到托管應用程序中

[英]Using DllImport to load unmanaged dll into managed application

在我的項目中,我有一個非托管的本機C ++ DLL和一個C#應用程序。 我試圖使用DllImport從非托管DLL導入一個函數,但我一直得到一個DllNotFoundException。

這是我調用DLL的代碼。

using System.Runtime.InteropServices;
namespace TestApp
{
  public delegate void UpdateDelegate(string s);
  class Program
  {
    [DllImport("CGPUnmanagedLibrary.dll")]
    internal static extern int parse_raw_gsod_file( 
      [MarshalAs(UnmanagedType.LPStr)]                                               
      string filePath,
      int minTemp, 
      UpdateDelegate callBack);

    static void Main(string[] args)
    {
      UpdateDelegate myCallBack = new UpdateDelegate(Program.Report);
      string path = @"C:\Creative Solutions\Projects\Clyde's Garden Planner\Frost Data Database\GSOD Data\GSOD_RAW_DATA\1992\gsod_1992.txt";
      int result = parse_raw_gsod_file(path, 32, myCallBack);
      Console.Write("Parse completed with exit code: " + result.ToString());
      Console.ReadLine();
    } // end main function

    public static void Report(string msg)
    {
      Console.Write("Message is ");
      Console.WriteLine(msg);
    }

  } // End class
} // end namespace

我嘗試將DLL復制到app輸出目錄,但仍然無法找到它。 我也嘗試添加DLL項目作為參考,但我得到一個彈出窗口,說它無法添加。 如何正確地將無人DLL鏈接到托管應用程序?

更新 - 這是完整的錯誤:

Unable to load DLL 'CGPUnmanagedLibrary': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

更新2 - 我確定DLL與嘗試加載它的.exe位於同一目錄中。 這讓我覺得DLL中存在一個未加載的依賴項。 我只在DLL中使用基本的C ++庫(字符串,數學,iostream等)。 什么想法無法加載,為什么?

更新3 - 使用Dependency Walker測試在依賴walker中加載我的非托管C ++ DLL顯示沒有錯誤。 我還嘗試在依賴walker中打開我的可執行文件,它顯示加載兩個DLL的錯誤:GPSVC.DLL和IESHIMS.DLL - 沒有任何意義,因為我只在我的代碼中使用標准的c ++庫。 我認為這可能與我有一個托管C ++ / CLI DLL試圖加載非托管DLL的事實有關(我試圖實現一些C ++ / CLI包裝器)。 無論如何,我已經開始了一個新的VS解決方案並繼續前進。 看我的回答。

很可能問題不是你試圖加載的DLL,而是它的一個(鏈接的)依賴項。 在DLL上運行depends.exe或類似的實用程序,以查看是否可以找到所有依賴項。 誤導性消息“無法找到指定的模塊”已經成為一個經典的煩惱(如果不是常見問題解答材料!):它會讓你認為你的DLL幾乎沒有被發現它幾乎所有的時候它都是它的依賴之一被發現。

要進行測試,* .dll需要與嘗試加載它.exe位於同一目錄中 此時不要相信Visual Studio會為您執行此操作。 將文件物理復制到C:* ***** \\ Debug \\ x86 \\ bin \\或您正在運行的任何配置。 如有疑問,請將其復制到所有bin文件夾中。 找出路徑后,您就開始尋找自動化項目構建的方法來正確復制文件。 如果不這樣做,將它放在system32中 - 它肯定會在那里找到它。 但是,如果做完這些事后,你仍然找不到它。 可能存在對您的非托管dll的依賴,這也是缺失的。

首先,我要感謝大家的幫助。 不幸的是,我從未解決過這個問題(請參閱我的主要問題中的編輯)。 答案結果是開始一個全新的Visual Studio解決方案並創建兩個新項目:C#app和C ++ dll。 我取消了對包裝器的需求,因為我現在正在編組兩個主要功能。

再次感謝。

用戶arayq2的答案非常有意義,我很快就能解決我的問題。

在我的情況下無法加載的DLL(DllNotFoundException)取決於另一個DLL。 這個dll(不是我的項目的一部分)實際上是使用某些.h和.lib文件的較新版本編譯的。 這些.h和.lib文件的舊版本(具有相同的文件名)是編譯無法加載的dll的項目的一部分。

在我使用這些.h和.lib文件的較新版本更新我的dll項目並重新編譯我的dll項目后,我的問題就解決了。

謝謝arayq2!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM