2016-04-13 13 views
1

Windows 7 Pro 64ビット版でmingw-w64を使用しています。外部変数にアクセスしようとするには、多くの毛の裂けた後、私は最終的にこのに到着:私は働いているので別のファイルからC++のextern "C"変数にアクセスする

// MultiTest2.h 
// Version 1.0.0 
// MDJ 2016/04/13 

#ifndef MULTITEST2_H 
#define MULTITEST2_H 

extern "C" { 
    int iXfer; 
    int setInt(); 
} 

#endif // MULTITEST2_H 

は(私が代わりに単に「のextern」のはextern 『C』 'を使用しています動作しません。最終的にアセンブリコードにリンクすることになります):

// MultiTest2.h 
// Version 1.0.1 
// MDJ 2016/04/13 

#ifndef MULTITEST2_H 
#define MULTITEST2_H 

extern "C" int iXfer; 
extern "C" int setInt(); 

#endif // MULTITEST2_H 

が動作します!

はFYI、システム内の他の2つのファイルがある:

// MultiTest2.cpp 
// Version 1.0.0 
// MDJ 2016/04/13 

#include "MultiTest2.h" 

int iXfer = 0; 

int setInt() { 
    iXfer = 6253; 
    return 0; 
} 

と:MultiTest2.hのバージョン1.0.0「にextern "C" で(宣言して

// MultiTest1.cpp 
// Version 1.0.0 
// MDJ 2016/04/13 

#include <iostream> 
#include "MultiTest2.h" 

using namespace std; 

int main() { 
    setInt(); 
    cout << iXfer << endl; 
} 

直ちに入る 'ブロック):

g++ -S MultiTest2.cpp 

結果は:

MultiTest2.hのバージョン1.0.1と

MultiTest2.cpp:7:5: error: redefinition of 'int iXfer' 
int iXfer = 0; 
    ^
In file included from MultiTest2.cpp:5:0: 
MultiTest2.h:12:6: note: 'int iXfer' previously declared here 
    int iXfer; 
    ^
しかし、(個人のはextern "C"」宣言が)、以下の手順では完璧に動作します:

c:\work\gccWork\MultiTest>g++ -S MultiTest2.cpp 
c:\work\gccWork\MultiTest>g++ -S MultiTest1.cpp 
c:\work\gccWork\MultiTest>g++ -c MultiTest2.s 
c:\work\gccWork\MultiTest>g++ -c MultiTest1.s 
c:\work\gccWork\MultiTest>g++ -o MultiTest.exe MultiTest2.o MultiTest1.o 
c:\work\gccWork\MultiTest>MultiTest 
6253 

はmingwの-W64 idiosyncracyのこのいくつかの並べ替えです、または私はここに行方不明のものがありますか?

答えて

0

これらは同じではありません。

extern "C" int foo; 

は、2つのことを行います。それは(つまり、これが唯一の宣言です、そしてシンボルが別のモジュールで定義されます)fooははexternであることを宣言し、それが「C」としてFOOのリンクを宣言し、その影響シンボル名。

一方、

extern "C" { 
    int foo; 
} 

のみfooがCのリンクを有することを宣言する。シンボルをexternとして宣言しません。これは、宣言だけでなく定義でもあることを意味します。つまり

extern "C" int foo; 

extern "C" { 
    extern int foo; 
} 
+1

(にexternキーワードの繰り返しに注意してください)と同じである "これは、シンボルのexternをしない..." 正確ではありません。名前空間スコープで宣言された非constオブジェクトは、デフォルトで外部リンケージを持ちます。とにかく「外に出す」必要はありません。 'extern" C "は、この場合、*定義*を定義しない宣言*(普通のexternはそうします)に変換しません。 – AnT

+0

@AnTありがとう、私は言葉を更新しました。 – AaronI

関連する問題