繁体   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