【问题标题】:How to handle C# - C++ project interaction the right way?如何正确处理 C# - C++ 项目交互?
【发布时间】:2011-11-11 23:42:08
【问题描述】:

我真的需要更深入地了解如何正确设置以在我的 C++ 和 C# 代码库之间实现优雅的交互。 我想要实现的是一个用 C# 为我的游戏引擎 (C++/DX) 编写的游戏内编辑器。为此,我让 VS 将我的引擎构建为带有一些附加功能(非托管代码)的 C++ dll,以从 C# 编辑器代码库访问我的引擎所需的功能。到目前为止一切顺利。

困扰我的第一件事是我必须使用 CLR 支持构建 dll。否则 C# 出于某种原因不接受 dll。它甚至不允许我将其添加到资源中(“无法添加对 'C:\Users...\frame_work\Test\frame_workd.dll' 的引用。请确保该文件可访问,并且它是一个有效的程序集或 COM 组件。”)。

当我使用 CLR 支持构建 dll 并将其添加到 C# 中的引用时,在没有 CLR 支持的情况下重新构建,启动我的编辑器并从 dll 进行函数调用,然后我得到一个异常 HRESULT: 0x8007007E。我搜索了它,但我发现唯一的东西与依赖关系有关,但这不符合我在将 dll 添加到资源时收到的警报。

另外一点是我总是要在应用程序(.exe)和dll之间切换配置类型。在 VS C++ 中取决于我是想直接运行我的引擎还是从编辑器运行我的引擎,并且每次构建完整的项目时都是全新的。

那么,有人可以向我解释如何以正确的方式组织这个吗? C# 想要使用 CLR 支持编译 dll 的可能原因是什么?

谢谢你们。

【问题讨论】:

    标签: c# c++ dll


    【解决方案1】:

    有两种方法可以解决这个问题。

    您可以让您的 C++ 代码提供一个具有完全兼容 COM 对象的 API。如果对象是 COM,那么 C# 可以直接与它互操作。 (这就是为什么你不能直接添加它作为参考)

    但是我认为您真正想做的将涉及 P/Invoke(从 C# 调用 C/C++ 本机代码)。这是完全可能的,但并不总是那么容易。您需要处理 C++ API 和 C#、指针之间的转换,并且需要非常小心地将 C++ 代码写入 C# 应用程序中的任何引用。

    【讨论】:

      【解决方案2】:

      C# 代码是托管代码(在 CLR 中运行),只能直接* 引用托管程序集。因此,当然,当您针对托管程序集进行构建时,您会遇到错误,然后潜入并用(不兼容的)非托管 DLL 替换该托管 DLL。您基本上是在试图对编译器撒谎,而这通常不会很好地结束。

      如果您希望您的 C++ DLL 可以从 C# 访问,最简单的方法是将其构建为托管程序集(即 CLR 支持)。您已经在这样做了。只需采取额外的步骤,将工作的托管 DLL 替换为非工作的非托管 DLL。

      还有:

      带有一些附加功能(非托管代码)的 C++ dll 可从 C# 编辑器访问我的引擎所需的功能

      这对你没有帮助,因为 C# 不能直接* 调用非托管代码。完成这项工作的最简单方法是在您的 C++ DLL 中创建额外的托管类和方法。然后您的 C# 程序集将能够直接使用这些托管类。

      * 作为 Spence noted,您可以使用 -indirect- 方法(P/Invoke 和 COM)从 C# 访问非托管代码。但这将使您的生活比现在复杂得多,更不用说它会使您的构建和部署变得多么复杂。你已经非常接近应该工作的东西了——不要增加所有额外的复杂性。

      【讨论】:

      • 现在一切正常。唯一的错误是我将 dll 添加到引用中,即错误的位置。它现在在没有 CLR 支持的情况下工作。谢谢你的回答。 @Spence
      • 强制管理您的 api 的能力并不总是一种选择。
      【解决方案3】:

      当使用 P/Invoke 调用函数时,您不会将 DLL 添加到 C# 项目资源(或者您可能的意思是引用)。

      当然,您会将其添加到您的 MSI 项目的文件列表中。

      【讨论】:

      • 你说得对,我的意思是“参考”。我认为这是放置它的正确位置,因为我总是将我的 dll 的最新副本放在我的编辑器的应用程序文件夹中。不过,谢谢。
      猜你喜欢
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      相关资源
      最近更新 更多