3

在我的项目中,我有一个非托管的本机 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 复制到应用程序输出目录,但仍然找不到。我也尝试添加 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 未显示任何错误。我还尝试在依赖项步行器中打开我的可执行文件,它显示加载两个 DLL 时出错:GPSVC.DLL 和 IESHIMS.DLL - 没有任何意义,因为我只在我的代码中使用标准 c++ 库。我认为这可能与我有一个托管 C++/CLI DLL 试图加载非托管 DLL 的事实有关(我试图实现一些 C++/CLI 包装器)。无论如何,我已经开始了一个新的 VS 解决方案并继续前进。看我的回答。

4

4 回答 4

4

问题很可能不是您尝试加载的 DLL,而是它的(链式)依赖项之一。在 DLL 上运行 depends.exe 或类似的实用程序,以查看是否可以找到所有依赖项。误导性消息“找不到指定的模块”已成为经典的烦恼(如果不是常见问题解答材料!):它使您认为几乎所有时间都找不到您的 DLL,但它是它的依赖项之一。被发现。

于 2013-01-26T03:05:36.940 回答
2

要进行测试,*.dll 需要与尝试加载它的 .exe 位于同一目录中。此时不要相信 Visual Studio 会为你做这件事。将文件物理复制到 C:* *****\Debug\x86\bin\ 或您正在运行的任何配置。如有疑问,请将其复制到所有 bin 文件夹中。找出路径后,您开始寻找自动化项目构建以正确复制文件的方法。如果不这样做,把它放在 system32 中——它肯定会在那里找到它。但是,如果在做了这些事情之后,你仍然找不到它。可能还缺少对您的非托管 dll 的依赖项。

于 2013-01-26T01:36:16.117 回答
0

首先我要感谢大家的帮助。不幸的是,我从未解决过这个问题(请参阅我的主要问题中的编辑)。答案是启动一个全新的 Visual Studio 解决方案并创建两个新项目:C# app 和 C++ dll。我不再需要包装器,因为我现在只是编组两个主要功能。

再次感谢。

于 2013-01-30T02:10:51.627 回答
0

用户 arayq2 的回答很有意义,我也很快能够解决我的问题。

在我的情况下,无法加载的 dll (DllNotFoundException) 取决于另一个 dll。这个 dll(不是我项目的一部分)实际上是用某些 .h 和 .lib 文件的较新版本编译的。这些 .h 和 .lib 文件的旧版本(具有相同的文件名)是编译无法加载的 dll 的项目的一部分。

在我用这些 .h 和 .lib 文件的较新版本更新我的 dll 项目并重新编译我的 dll 项目后,我的问题就解决了。

谢谢你 arayq2!

于 2016-06-25T20:39:55.967 回答