C链接和C++头文件

问题描述:

我想在C链接的共享库中使用一些C++类。我有以下问题。C链接和C++头文件

如果

#include <iostream> 
extern "C" 
{ 
void f(){} 
} 

编译并成功地链接,但F()不能在导致库中找到。

如果

extern "C" 
{ 
#include <iostream> 
void f(){} 
} 

我得到了很多的编译器错误(只是不知道如何用英语,一些关于C链接模板正确地翻译它们)iostream中对C++的关键字“模板”的每一次出现,其中包括报头。

应该做什么?

第一个变体是正确的。只有存在于C中的东西才能在extern "C"块中声明,而模板和类当然不属于该类别。如果您使用的是C++编译器,则只需确保您的函数在头文件中也声明为extern "C"。这通常通过书写

#ifdef __cplusplus 
// C++ declarations (for example classes or functions that have C++ objects 
//     as parameters) 

extern "C" 
{ 
#endif 

// C declarations (for example your function f) 

#ifdef __cplusplus 
} 
#endif 

在标题中。

+0

谢谢。它工作完美。 – Alexander 2012-01-11 10:16:18

使用__declspec导出函数,类等等...... 另外:http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx

而这一次是非常好的:http://www.flounder.com/ultimateheaderfile.htm

+0

这是不可移植的,OP没有说他使用了什么编译器。 – filmor 2012-01-11 10:06:36

+0

是的,忘了说。我使用gcc 4.6.1和Linux。 – Alexander 2012-01-11 10:17:28

+0

您不必使用declspec(即使在Windows上),并且通过使用extern“C”,它与其他C++编译器以及可能的C代码本身交叉兼容。 如果这是在Windows平台上构建的,那么您将使用.def文件在导出表中声明该符号。 – CashCow 2012-01-11 12:12:20

首先是正确的;系统标头(以及大多数其他标头) 只能包含在全局范围内,不包括任何名称空间,类,功能或链接规范块。有在 <iostream>容易的事情,不会在extern "C"是合法的,即使 有没有,名字改编为extern "C"几乎可以肯定是从C++的 不同,库本身是肯定编译 为extern "C++"

你是怎么定义f的?这可能是一个类似的问题:如果源 文件将其编译为extern "C++"函数,则名称将为 与编译为 和extern "C"函数的客户端文件不同。

这里的一般政策是处理头和功能,你通常会做同样的方式 定义/声明,除了 可以确保头可以被包含在C和C++源代码, 如:

#if __cplusplus 
extern "C" { 
#endif 
void f(); 
// Other `extern "C"` functions... 
#if __cplusplus 
} 
#endif 

然后包括在所有文件此头其中函数f()被使用, 并且其中它被定义在文件中。