1

我想在具有 C 链接的共享库中使用一些 c++ 类。我遇到了以下问题。

如果

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

编译和链接成功,但在生成的库中找不到 f()。

如果

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

在 iostream 中每次出现 C++ 关键字“模板”并包含头文件时,我都会遇到许多编译器错误(只是不知道如何正确地用英语翻译它们,关于带有 C 链接的模板)。

应该做什么?

4

3 回答 3

4

第一个变体是正确的。只有 C 语言中存在的东西才能在extern "C"块中声明,模板和类当然不属于该类别。extern "C"如果您使用的是 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

在标题中。

于 2012-01-11T09:52:38.767 回答
2

第一个是正确的;系统头文件(以及大多数其他头文件)只能包含在全局范围内,在任何命名空间、类、函数或链接规范块之外。<iostream>可能extern "C"有一些东西 extern "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()使用该函数的所有文件中,以及定义它的文件中。

于 2012-01-11T10:11:08.713 回答
0

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

而这个非常好:http ://www.flounder.com/ultimateheaderfile.htm

于 2012-01-11T10:04:50.330 回答