2008-04-08

LNK2005エラー

今日はつまらない失敗談です。
C言語初心者なので いつも1つのファイルにプログラムを書いているのですが、たまにはカッコをつけてファイルを分割しようとしてみました。
 
白本を参考に(というかほとんどそのまま)GPSからの状態取得のコードを書いてみたのですが、いざリンクするとエラーが出てきます。
error LNK2005: "unsigned long g_dwGpsSatelliteCount" (?g_dwGpsSatelliteCount@@3KA) は既に WhereNow.obj で定義されています
error LNK2005: "double g_dblGpsLatitude" (?g_dblGpsLatitude@@3NA) は既に WhereNow.obj で定義されています。
error LNK2005: "double g_dblGpsLongitude" (?g_dblGpsLongitude@@3NA) は既に WhereNow.obj で定義されています。
 
GPSの座標等をグローバル変数で受け渡そうとして(既にこの辺に問題があるような気もしますが...)、ヘッダファイルで変数を公開していました。
HANDLE  g_hGpsDevice            = NULL;
DWORD   g_dwGpsSatelliteCount   = 0;
DOUBLE  g_dblGpsLatitude        = 0.0,
        g_dblGpsLongitude       = 0.0;

VOID GpsStart(HWND);
VOID GpsEnd();
 
かすかな記憶を頼りに二重定義防止のおまじないを入れてみたのですが、結果は同じ。
#ifndef _MY_GPS_H_
#define _MY_GPS_H_
    :
    :
#endif // _MY_GPS_H_
 
ここでCの入門書を引っ張り出して 1時間くらい中断。やっと答えを見つけました。
 
ヘッダファイルでグローバル変数を定義したら上のおまじないをしても定義が重複してしまうんですね。
という訳でグローバル変数は .cppの中で定義して、ヘッダファイルには externを付ける事で解決。
extern HANDLE   g_hGpsDevice;
extern DWORD    g_dwGpsSatelliteCount;
extern DOUBLE   g_dblGpsLatitude,
                g_dblGpsLongitude;
 
外部に公開しているものを書いているという思い込みがあったのですが、コンパイラ側にしてみれば#includeされる度にヘッダファイルを読み込んでいるだけなんですよね。
せっかくの .cppなのだから namespaceとかを使うべきなのかもしれませんね。
 

0 件のコメント: