使用C++链接C库

3

我创建了一个dll文件。这个文件是编译成C代码的。我想在一个新项目中使用这个dll文件。这个新项目是一个C++项目。如果我编译我的新项目,一切都很好,但当项目编译为C++程序时,由于从dll文件中导出的函数未解析而出现无法解决的外部符号错误。我希望我的新项目是一个C++程序,但想要链接一个以C程序编译的库。我正在使用Visual Studio 2010。有没有帮助?

3个回答

9

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

#ifdef __cplusplus 
extern "C" {
#endif

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

#ifdef __cplusplus
}
#endif

7

您需要在导入的过程的头文件声明中使用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”。 - delete_this_account
@goygoycu 在 C 库中不能使用 C++ 数据类型,我猜这里正在尝试类似的操作。 - Mark B
1
@goygoycu 我给出的例子是正确的。我不确定你的错误,因为我看不到你的代码。 - David Heffernan
我在C语言中没有使用任何C++数据类型。如果我写extern "C" __declspec(dllexport) int raxml_main(int argc, char* argv[]);,就会出现错误。 - delete_this_account
@goygoycu,你已经将它添加到了C代码中。extern "C"是C++的语法,因此在C代码中不需要指定C链接。将其添加到您用于导入到C++代码中的头文件中。使用bcsanches所示的#ifdef语句。 - David Heffernan

5

在将C头文件添加到C++项目时,请执行以下操作:

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

这可以防止C++编译器对cheader.h中定义的名称进行名称重整

你甚至可以定义一个命名空间,如下:

namespace cproject
{
    extern "C"
    {
       #include "cheader.h" //C header 
    }    
}

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

不是我。我认为你应该说一些关于如何管理这样的包含文件的内容,即您呈现的两个摘录本身需要在头文件中。 - David Heffernan
@David: 解释这个需要花费时间和精力。而我已经很累了,感觉想睡觉。现在是印度的凌晨12点44分。 :-) - Nawaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接