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"は 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 に答える