用 C++ 链接 C 库

Posted

技术标签:

【中文标题】用 C++ 链接 C 库【英文标题】:Linking C libraries with a C++ 【发布时间】:2011-04-18 18:53:39 【问题描述】:

我创建了一个 dll 文件。该文件被编译为 C 代码。我想在一个新项目中使用这个 dll 文件。这个新项目是一个 C++ 项目。如果我编译我的新项目,一切都很好,但是当项目被编译为 C++ 程序时,它会为从 dll 文件导出的函数提供未解决的外部符号错误。我希望我的新项目是一个 C++ 程序,但想链接一个编译为 C 程序的库。我正在使用 Visual Studio 2010。有什么帮助吗?

【问题讨论】:

【参考方案1】:

另一种方法是更改​​ C 头文件以检查是否正在由 cpp 编译器编译并有条件地包含 extern "C":

#ifdef __cplusplus 
extern "C" 
#endif

void func1(int a, int b);
//... other functions

#ifdef __cplusplus

#endif

【讨论】:

【参考方案2】:

您需要在导入过程的头文件声明中使用extern "C",以便使用C 链接。

目前正在发生的事情是 C++ 编译器期望您导入的函数名称不正确。使用 extern "C" 关闭 C++ 名称修改。

例如:

extern "C"

    int Func1(int a, int b);
    void Func2(double a);

由于您可以控制头文件,因此将extern "C" 放在头文件中更有意义。这意味着使用您的头文件的任何人都不需要关心这些问题。但是,当包含您无法控制的头文件时,@Nawaz 的建议是一种巧妙的方法。

我还忘了提到 @bcsanches 提出的一个很好的观点,即 extern "C" 是 C++ 而不是 C。因此,如果您希望单个头文件同时适用于 C 和 C++,则需要有条件地包含它。

【讨论】:

谢谢,但它给出了一个奇怪的错误:错误 C2059:语法错误:'string'。 @goygoycu 你不能在 C 库中使用 C++ 数据类型,我假设这里正在尝试类似的东西。 @goygoycu 我给出的例子是正确的。我不确定您的错误,因为我看不到您的代码。 我没有在 C 中使用任何 C++ 数据类型。如果我写 extern "C" __declspec(dllexport) int raxml_main(int argc, char* argv[]);它给出了那个错误。 @goygoycu 您已将其添加到 C 代码中。 extern "C" 是 C++。您不需要在 C 代码中指定 C 链接。将其添加到用于将其导入 C++ 代码的头文件中。使用 bcsanches 显示的 #ifdef。【参考方案3】:

将 C 头文件添加到 C++ 项目时执行此操作:

extern "C"

   #include "cheader.h" //C header 

这会阻止 C++ 编译器对 cheader.h 中定义的名称执行 name-mangling

您甚至可以将命名空间定义为:

namespace cproject

    extern "C"
    
       #include "cheader.h" //C header 
        

如果您这样做,那么当您引用cheader.h 中定义的名称时,您必须使用cproject:: 限定每个名称(函数、变量、结构)。

【讨论】:

不是我。我认为您应该谈谈如何管理此类包含,即您提供的两个摘录需要它们自己位于头文件中。 @David:解释这需要时间和精力。而且我已经很累了,感到困倦。它在印度的 12:44 AM。 :-)

以上是关于用 C++ 链接 C 库的主要内容,如果未能解决你的问题,请参考以下文章

想【C++ 】高手发起挑战,请教一个【动态链接库 dll 和 类成员函数 显式链接】问题

Visual C++ 2017,外部“C”被忽略了吗?将 C++ 代码链接到 C 库时出现 LNK2019 错误

c++静态库链接顺序引发的bug

如何正确链接/包含 c++ 库

visual studio 2008 c++ 中怎样添加动态链接库?

如何在C语言中调用C++做的动态链接库