【问题标题】:Build and deliver a C/C++ DLL into a C# app using Visual Studio 2013使用 Visual Studio 2013 构建 C/C++ DLL 并将其交付到 C# 应用程序中
【发布时间】:2014-08-26 19:06:06
【问题描述】:

我是一名 Visual Studio 2013 新手,正在尝试弄清楚如何在 Visual Studio 中构建 C DLL,然后从 C# 应用程序中调用 C lib 导出的函数。我已经构建了所有内容,但我无法弄清楚将 DLL 包含在应用程序构建中的正确方法,以便在使用 [DLLImport()] 时它实际上会正确加载。我目前在尝试从我的 C# 类中调用库中的函数时收到 System.DllNotFoundException

我已经设置了一个 VS 2013 解决方案,其中包含以下项目:

HelloWorldLib.Shared: 包含 DLL 的 .cpp 和 .h 文件的共享项目

HelloWorldLib.Windows: 引用共享项目并为 Win 8.1 构建 DLL 的 Win 8.1 C++ 项目

MyApp-Win.Windows: 想要使用 HelloWorldLib.windows 构建生成的 HelloWorldLib.Windows.dll 的 Win 8.1 的 C# 项目

我一直在查看许多 SO 问题和答案。例如,我认为我的问题与这个问题类似,但似乎没有以任何有用的方式回答: Interop, Native DLL and Visual Studio build process

其他一些答案建议添加对 DLL 的文件引用,但我将如何做到这一点并保持正确的调试/发布版本?鉴于所有这些项目都在同一个解决方案中构建,并且它们之间存在构建依赖关系,感觉应该有一种直接的方式来设置它。

顺便说一句,我正在使用共享项目设置,因为我的最终目标是弄清楚如何让这一切与 Xamarin 一起工作,以针对 iOS、Win、Win Phone、Mac 和 Android。这样我们就可以为我们的高性能需求代码使用一个通用的 C/C++ 层,并从各个平台的 UI 层中引用它。

【问题讨论】:

  • 您知道您需要为每个平台重新编译本机部分,对吗?
  • 是的。我意识到需要为每个平台编译本机库。我的期望是,由于我已经构建了从“应用程序项目”到“DLL 项目”的依赖项和引用设置,因此当我为每个平台构建应用程序时,VS 将同时构建正确的本机 DLL。从构建日志中可以看到,它似乎确实做到了这一点,但我无法弄清楚如何让构建的 DLL 包含在应用程序中。

标签: c# visual-studio visual-c++ dll xamarin


【解决方案1】:

这是一个非常直接的问题,如果您查看构建文件的最终位置,很容易识别。 C++ 构建系统具有与托管构建系统不同的策略。默认情况下,它将构建输出写入解决方案目录的 Debug 目录。但是,您的 C# 项目会构建到它的 bin\Debug 目录,并要求所有相关的 DLL 都存在于该目录中。

因此,默认情况下,您的 C# 程序永远无法找到 DLL,它位于错误的目录中,而 Windows 不会在那里查找。 MSBuild 也不够聪明,无法自行发现这一点,就像它可以用于托管 DLL 一样,它无法看到您的程序依赖于 C++ DLL。

解决此问题的两种基本方法:

  • 更改 C++ 项目的输出目录设置
  • 为使用 xcopy.exe 复制 DLL 的 C# 项目编写构建后事件。

【讨论】:

  • 谢谢汉斯 - 很好的解释。所以本质上,Visual Studio 只知道如何管理托管 DLL 和非托管 DLL 之间的依赖关系。这就解释了为什么我很难找到一种自动执行此操作的方法。我猜必须更改输出目录设置才能将其转到 C# 输出目录?我相信 VS 中有宏可以用来确保它根据构建类型进入正确的目录?
【解决方案2】:

不幸的是,事情并没有那么容易,至少现在还没有。我本来打算与 Microsoft C++ 团队开会,但那次会议被推迟了,您所追求的类似功能是我的愿望清单上的事情之一(为 Xamarin.iOS 和 Android 构建托管 C++/CLI 包装器)。

目前,如果可以的话,最简单的选择是将 C++ 代码包装在公开 C 接口的 DLL 中。然后使用 XCode 和 Android NDK 构建它。如果你不能,那么下一个选项是创建 Objective-C 绑定项目,将 C++ 代码包装在 iOS 的 Objective C 类中。对于 Android,要么创建 Java 包装器,要么使用 SWIG。这两个选项都很麻烦,这就是为什么 C API 应该是您研究的首选。

我知道这不是您希望的答案,但重用 C++ 代码比重用 C# 甚至 C 复杂得多。

【讨论】:

  • 感谢您的回复。阅读了以下文章后,我倾向于只使用 C++,而不是使用 C#/Xamarin。 oleb.net/blog/2014/05/…
  • 为此,有一些可用于 C++ 的不错的框架,例如 juce.com/about-juceopenframeworks.cc,它们可能会使一些事情变得更容易。
  • 如果您的代码主要是 C++,那么这可能是最好的方法。我会看看 Qt,但缺点是生成的 UI 不会像 Xamarin 中那样是原生的。
  • 欣赏 Qt 建议。我们非常致力于为每个平台制作原生 UI。 Xamarin 可以在这方面提供一些帮助,但最终要获得良好的体验,我们仍然需要在 Xamarin.iOS、Xamarin.Android 和 Xamarin.Mac 以及 Windows 上做一些工作。
猜你喜欢
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 2010-09-09
相关资源
最近更新 更多