【问题标题】:How to call C DLL functions C++/CLI如何调用 C DLL 函数 C++/CLI
【发布时间】:2014-05-16 18:01:39
【问题描述】:

我已经查看了很多在线搜索,并且大多数都有一些例子,它们谈论 C# 与 C 或 C++ 与 C#,但从未遇到过使用从 C++ 调用 C DLL(特别是在我的情况下从 C++/CLI 和 WPF 调用)。

有人可以举例说明如何在 C++ 中调用 C DLL 函数。我有一个 C DLL,它的所有函数都定义为 extern "C" funcName(),还有一个导出函数 .def 文件,其中包含所有需要导出的函数名称。现在有了这个 C DLL,我如何在 C++ 代码中调用它的导出函数。

谢谢。

【问题讨论】:

  • 直接调用导出的函数即可。这完全是使用 C++/CLI 的重点。
  • @HansPassant 它几乎那么容易......但并不那么容易。必须像往常一样链接。必须将包含在 exten C 中。

标签: c++ c dll c++-cli


【解决方案1】:

好的,所以“带有 C++ 的 WPF”不是一种语言。 WPF 是一个 .NET 库。 C++/CLI 是您编写的语言。

从 C++/CLI 调用 C dll “非常简单”,具体取决于 DLL 的导出方式。您可以使用 .NET 库来执行此操作,也可以使用 C 库(我建议使用 C 库)。链接到 dll 有两种方法:隐式链接或显式链接。

隐式链接更简洁,恕我直言。但是您需要访问一个头文件(编辑:可能带有 declspec 装饰,请参阅下面的 BenVoigt 的注释)和一个 .lib 文件。如果你有这些,只需将.lib文件添加到附加依赖项(右键单击项目->属性->配置属性->链接器->输入)并将头文件路径添加到包含(右键单击项目->属性->配置属性->C/C++->常规)。然后您可以将头文件(用于提及这一点的 metacubed 的道具)包含为外部“C”头文件:

extern "C"
{
   #inlude "c_header.h"
}

(这是因为 C++ 会进行名称修改,以便您可以重载、命名空间、类和其他东西。如果您不这样做,它会将您的 C 头文件解释为 C++ 头文件(并修改您的所有名称)使用extern "C")

http://msdn.microsoft.com/en-us/library/d14wsce5.aspx

或者你可以显式链接

http://msdn.microsoft.com/en-us/library/784bt7z7.aspx http://msdn.microsoft.com/en-us/library/zzk20sxw.aspx

但我怀疑确定您使用的是 C++/CLI,这会告诉您要搜索什么。 (虽然 C++ 的答案也适合你)。

对于 .NET 方式,一个简单的技巧是查找 C# 调用(请注意,这也是显式链接,因此不需要 .lib 文件和标头)。

http://msdn.microsoft.com/en-us/library/eyzhw3s8.aspx

现在棘手的一点是,如果您正在使用 C++/CLI 并希望将您喜欢的托管类转换为 C 形式,您必须编组代码。这是一个方便的链接,指向一个向您展示如何操作的表格。

http://msdn.microsoft.com/en-us/library/ac7ay120%28vs.71%29.aspx

【讨论】:

  • 抱歉,我很快将我的问题从 C++ 改成了 C++/CLI,但我想在我编辑的时候,你已经发现我错了。 :-) 感谢您的回答,我将尝试使用您的隐式链接解决方案,我怀疑但希望专家对此提出建议。谢谢!
  • 不需要 declspec 装饰。实际上,这就是导入库的全部意义。
  • @BenVoigt 据我所知,从 dll 中,隐式链接需要 __declspec(import)。 msdn.microsoft.com/en-us/library/zw3za17w.aspx。显式链接不需要它,但需要您调用 LoadLibrary 并做更多的事情。虽然你适合静态库。
  • @madsciencedreams,我不知道你是如何将“节省 thunk 但减慢 DLL 加载”变成“必需”的。
【解决方案2】:

从 C++ dll 调用 C dll 函数是完全一样的,无论是 WPF、C++/CLI 还是原生 C++。

  1. 包括头文件。语法见下文。
  2. .lib 作为导入依赖项添加到您的项目中。还将链接器设置为使用 DLL。有关所有详细信息,请参阅 Linking implicitly
  3. 确保程序执行时使用的 DLL 存在于运行时类路径中。
  4. 使用头文件中定义的函数。

头文件include应该声明为:

extern "C" {
    #include "c_header.h"
}

就是这样!

编辑:另外,请查看:Call a C function from C++ code

【讨论】:

  • 感谢 metacubed、@MadScienceDreams 和其他人的反馈。在更好地理解了“隐式链接”和“显式链接”之间哪种机制最有效之后,我发现我必须使用显式链接,因为我知道我想在运行时而不是在编译期间链接 DLL时间。我打算使用我的 WPF 应用程序加载一个 DLL,然后使用我加载的 DLL 中的导出函数。但是我很难理解如何在用 C++/CLI 环境编写的 WPF 应用程序中做到这一点。解释 WPF 中的显式链接的任何进一步帮助都会有所帮助。
猜你喜欢
  • 2011-06-16
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多