【问题标题】:Reference an unmanaged C++ DLL from Managed C++从托管 C++ 引用非托管 C++ DLL
【发布时间】:2013-01-07 22:33:16
【问题描述】:

这个问题来自我之前的问题:Create DLL from unmanaged C++,但您不必阅读它就可以理解这个新问题。

我现在有一个 DLL,其中包含由几个函数组成的非托管 C++ 代码,我只导出其中一个以供外部使用。接下来,我需要在托管 C++ 项目(使用公共语言运行时支持构建)中使用此 DLL。到目前为止,我已经通过在 Visual Studio 2010 中设置 Additional Include Directories 添加了对现有非托管项目的头文件的引用。

如果我现在尝试添加对 DLL 文件的引用:MyManagedProject > Properties > Common Properties > Add New Reference > Browse > MyUnmanagedDLL.dll,则会收到错误 Could not add a reference to file MyUnmanagedDLL.dll because it is neither a .NET assembly nor a registered ActiveX control. 但是,如果我使用前面提到的 DLL 并将其复制到与托管 C++ 的可执行文件相同的文件夹中,一切正常。

我不确定这是否是正确的方法,因为它似乎是一个 hackish 解决方案。此外,这意味着我每次更改其源代码时都必须复制 DLL。

总结一下我的问题:

  1. 我创建了一个由非托管 C++ 代码组成的 DLL,我们称之为MyUnmanagedDLL.dll。我还为这个 DLL 创建了一个头文件。
  2. 我有一个托管 C++ 项目 (CLR),我们称之为 MyManagedProject.vxproj
  3. 如何在MyManagedProject.vxproj 中使用MyUnmanagedDLL.dll?有没有正确的方法来引用它,还是我应该将它复制到与MyManagedProject.exe 相同的目录? (这行得通,但我不确定它是否是好的做法......)

额外信息:Windows 7、Visual Studio 2010 Ultimate、CMake 2.8.10.2

【问题讨论】:

    标签: c++ visual-studio-2010 dll clr unmanaged


    【解决方案1】:

    您不能将非托管 DLL 添加为对托管 C++ 项目的引用。您只能使用托管 DLL 来执行此操作。您所做的是链接到非托管 DLL,其方式与链接到非托管 C++ 项目中的非托管 DLL 的方式相同:

    • 使用头文件进行编译。
    • 将非托管 DLL 的 .lib 文件提供给链接器,例如将其添加到链接器配置页面中的附加依赖项列表中。
    • 把DLL和可执行文件放在同一目录下,这样加载器就可以定位到。

    【讨论】:

    • 感谢您的回复!目前,这就是我正在做的事情,除了你的第二点,我完全省略了。但是,它仍然可以正常工作。这是否意味着 .lib 文件是不必要的?我似乎隐约记得 .lib 文件的用途与头文件相似?
    • lib 文件是必需的。我猜链接器正在以某种方式找到它。当然,如果您实际上没有调用非托管 DLL 中的任何函数,那么链接器可以去除该依赖关系。确保您调用了非托管 DLL 以进行检查。
    • 是的,我确实调用了非托管DLL中的一个函数,然后调用了DLL中的其他函数,最终成功返回。所以这似乎没问题。我现在还添加了 .lib 文件,它看起来仍然很好。最好的方法是什么,我应该将非托管 DLL 包装在托管类中,然后构建一个托管 DLL?感谢您的帮助!
    • 嗯,这是一种非常常见的方法,它使非托管库的细节远离消费者。究竟如何最好地组织项目真的取决于你。我不想从对您的需求一无所知的立场上提出建议。
    • 好的,我将从这里提出一个新问题。干杯!
    【解决方案2】:

    显然,唯一的解决方案是在使用 DllImport 属性修饰的方法中传递非托管 dll 路径。

    您可以做的就是创建一个 lib 文件夹来放置非托管 dll 并将它们的属性“复制到输出目录”标记为“始终复制”(右键单击非托管 dll-> 属性-> 复制到输出目录:始终复制)。

    在您的方法 DllImport 属性中,您必须将参数指定为“lib/unmanaged.dll”。在 C# 中,你会有这样的东西。

    [DllImport("lib/testLib.dll")]
    private static extern int DisplayHelloFromDLL();
    

    这种方法与以前的答案没有区别,但它可以帮助您保持代码更整洁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 2011-03-04
      • 2011-04-29
      相关资源
      最近更新 更多