• ベストアンサー

グローバル変数

分割コンパイルで、持ちいる変数をヘッダーファイルに宣言しました。 ヘッダーファイル内で次のように宣言し、メインの関数でない場合にはexternになるようにしました。 メインなら FILEは1 それ以外なら0 #if FILE   unsinged int inputNo; #else  extern unsigned int inputNo; #endif しかし、リンクをさせると error LNK2001: 外部シンボル "_inputNo" は未解決です と出てしまいます。解決策はあるでしょうか? プロジェクトの設定の関係でしょうか?よろしくお願い致します。

  • R360
  • お礼率69% (365/524)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

それならうまくいくはずです。 メインでそれをincludeするに先立って、FILEが1になって'いない'としか考えられません。

R360
質問者

お礼

ありがとうございました。 解決いたしました。 *.cのファイルと*.cppファイルを今度していたのも原因のひとつでした。

その他の回答 (1)

  • Fulu
  • ベストアンサー率52% (9/17)
回答No.2

参考までに、藤原博文さんの「改訂新版Cプログラミング診断室」(ISBN 4-7741-1787-0)の 90ページあたりも役に立ちます。簡単に説明すると、extern付きと externなしを1つにまとめられます。 (ちなみに藤原さんのWebページで全文が公開されています)

参考URL:
http://www.pro.or.jp/~fuji/
R360
質問者

お礼

ありがとうございました。

関連するQ&A

  • 質問させてください。

    質問させてください。 vista 32bit で VisualStudio2008pro を使い開発をしています。 ヘッダーファイルもインクルードし、 libファイルもリンクしているのですが、 下のエラーがなくなりません。 error LNK2001: 外部シンボル ""extern "C" int __stdcall aaaa(int,unsigned char *,unsigned char *)" (?aaaa@@$$J212YGHHPAE0@Z)" は未解決です。 DLLをインポートするヘッダーでは、 __declspec(dllimport)を使いインポートしています。 インポートのヘッダーは、64bit でも使っていて、 そちらはちゃんとコンパイルは通ります。 色々調べまわって、設定も色々変えてみたのですが 全然変わらないです。 本当に困っています。 わかる方がいられれば是非ご教授願います。

  • 動的ライブラリ中のグローバル変数

    以下の3行を前提条件とします。 メインのプログラムmainと動的ライブラリsub1.soとsub2.soがあります。 sub1.cとsub2.cにはsub.hというヘッダをインクルードしています。 mainはsub1.soおよびsub2.soを実行時に動的にリンクします。 ここでsub1.c中で int TEST=10;と変数を定義しました。 さらにsub.h中にextern int TEST;と変数を宣言しました。 そしてsub2.h中で if(TEST){…}と記述しました。 この状態でコンパイルを実行しました。 ここでmainを実行すると動きません。 調べてみるとsub2.soがTESTがundefined symbolとなっていました。 動的ライブラリ間での変数の共有の仕方は上の書き方では不正確なのでしょうか?

  • 変数宣言・変数定義のちがいって??

    変数宣言・変数定義のちがいって?? 同じ意味なんでしょうか? 私の解釈では、 ・宣言っていうのは、今からこの変数を使いますよってことで。 ・定義っていうのは、実際に変数の領域をわりあてるってイメージなんですけど・・ なので、 int a; ←これは変数定義 extern int a; ←これは変数(extern)宣言 あってるでしょうか?

  • 定義されているのにエラーになる

    閲覧ありがとうございます。 C言語のプログラムの話です。 ソースファイルaaa.cでstdio.hをincludeしています。 stdio.hには extern FILE _iob[_NIOBRW]; というのが定義されているにも関わらず、 コンパイルすると、 aaa.o:aaa.c:(.data+0x58): undefined reference to '_iob' というエラーが出ます。 aaa.cでは_iobに関する宣言はしていませんが、それを使うこともしていません。 ヘッダファイルでexternで宣言してるからかなと思い、ソースファイルにexternなしの宣言を書き足したら、コンパイルは通りました。 今回は元々既にあるプロジェクトの改修だったのですが、宣言を消したりしていません。 しかし、その部分は元々ヘッダファイルに宣言などしなくてもコンパイルが通ってました。 昔はヘッダファイルでexternで宣言してたらソースファイルではしなくてオッケーみたいな感じだったんですかね? 私自身、あまりよく分かってなくて文章もめちゃくちゃですみません。 不足している情報があればできる範囲でお伝えしますので、ご協力よろしくお願いいたします。

  • 猫でもわかるプログラミング161章

    http://www.kumei.ne.jp/c_lang/sdk2/sdk_161.htm にDLLを使ったメッセージフックについて説明があるのですが、どうもその通りにやってもうまくいきません。 まず、 1.dll作成する際にlibが生成されない。 2.ヘッダファイルに #define EXPORT extern "C" __declspec(dllexport) を付け加え、 EXPORT LRESULT CALLBACK .... という風にEXPORTをつけてビルドすると、libファイルが生成されるものの、それをメインプログラムのプロジェクトに追加しても リンク中... hookmain.obj : error LNK2001: 外部シンボル ""int __cdecl ResetHook(void)" (?ResetHook@@YAHXZ)" は未解決です hookmain.obj : error LNK2001: 外部シンボル ""int __cdecl SetHook(void)" (?SetHook@@YAHXZ)" は未解決です Debug/hook.exe : fatal error LNK1120: 外部参照 2 が未解決です。 link.exe の実行エラー というエラーが起きます。 このエラーが何を意味しているかもわからず、dllについても勉強中なのでどこを直せばいいかがみえてきません。どなたかわかる方がいらしたらよろしくお願いします VC++ 6.0 WinXP

  • プロジェクトを作った際のエラー

    VisualC++ 2005 Express Editionを使用してます win32コンソールアプリケーション - アプリケーション設定 - windowsアプリケーション この新しく作ったプロジェクトを何もいじらずにビルドすると __imp__EndPaint@8 が関数 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z) で参照されました。 test.obj : error LNK2019: 未解決の外部シンボル __imp__BeginPaint@8 が関数 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z) で参照されました。 test.obj : error LNK2019: 未解決の外部シンボル __imp__DefWindowProcW@16 が関数 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z) で参照されました。 test.obj : error LNK2019: 未解決の外部シンボル __imp__DestroyWindow@4 が関数 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z) で参照されました。 test.obj : error LNK2019: 未解決の外部シンボル __imp__DialogBoxParamW@20 が関数 "long __stdcall WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YGJPAUHWND__@@IIJ@Z) で参照されました。 test.obj : error LNK2019: 未解決の外部シンボル __imp__EndDialog@8 が関数 "int __stdcall About(struct HWND__ *,unsigned int,unsigned int,long)" (?About@@YGHPAUHWND__@@IIJ@Z) で参照されました。 C:\C++test\test\Debug\test.exe : fatal error LNK1120: 外部参照 19 が未解決です。 というエラーが出てしまいます 800文字オーバーしてしまうのでエラーの前半部分を消してあります この原因と解決方法を教えてください よろしくお願いします

  • SolarisとLinuxのグローバル変数の扱いについて

    Solaris用のソースをLinuxで使えるように変更したいのですが、 グローバル変数について以下のようなことが発生していて困っています。 なにか、コンパイルオプションなどで対応はできないものでしょうか? Solaris (CC)では 特にextern宣言しなくても同じシンボルの外部変数はコモンセグメントに1つだけ作成しコンパイル自体は正常である。 しかし、Linux (g++)では externを宣言しないと同じシンボルを再定義したことになりエラーとなる。 これにより、グローバル変数を多用しているプログラムはLinuxでうまくコンパイルができない。 しかし、単純にextern宣言での対応は難しい。 extern宣言は外部で定義してあるグローバル変数を参照する というものだがLinux では 1つの定義を意外は全てexternしなければ、2重定義エラーになってしまう。 つまり、実体が1つであとはそれを参照しているという形でなければいけない。 ところが、その実体をどこにするか特定することができない。 例えば、gというグローバル変数を仮定する。 A.c,B.c,C.cはその3つのソースよりAA.aという静的ライブラリを構成する。 gはA.cで定義してありB.c,C.cはそれを参照する。 ところが C.cは個別にC.oというオブジェクトで他からの呼び出しがあり 別LMにリンクされる。 その時C.c内のgは実体を失うことになり未定義となる。 つまり、どれが実体になるかは何にリンクするかで決まるため 実態を特定できない。 また、共通のヘッダにグローバル変数が定義されている場合も、重複するというエラーを起こすため、 共通ヘッダからグローバル変数を分離し、何れかのソースにグローバル変数の実態を定義させる必要がある。 共通ヘッダを使っている他のソースはそのグローバル変数の実態を参照するようにexternの宣言をする。

  • WindowsAPIでサブクラス化に挑戦しています。

    WindowsAPIでサブクラス化に挑戦しています。 C++での記述を意識していて、サブクラス化の要であるWNDPROC変数をクラス内にstaticで宣言したんですが error LNK2001: 外部シンボル ""public: static long (__stdcall* DialogSet::subInfoProc)(struct HWND__ *,unsigned int,unsigned int,long)" (?subInfoProc@DialogSet@@2P6GJPAUHWND__@@IIJ@ZA)" は未解決です。 というエラーが出力されて実行できないでいます。 CallWindowProc関数の第一引数にしてあるメンバ変数です。 静的なメンバにしたんですが、このエラーの解決方法をご存じならば是非、教えていただきたいです。

  • CとC++、どちらでコンパイルされているかをソース中で判別する方法

    タイトルのとおり、CとC++のどちらでコンパイルされているのかを、ソース中で判別する方法(#ifなど)を教えて下さい。 目的は、extern "C" という記述がCではエラーになってしまうのですが、CでもC++でもインクルード可能なヘッダファイルにするため、ヘッダファイル中で   #if「C++でコンパイル中」     extern "C" {   #endif としたいのです。 よろしくお願い致します。

  • VC2005のDLLを6.0で呼び出すには

    VC 2005 Pro Editionで作ったライブラリ(ヘッダ、lib、dll)を頂きました。    頂いたDLLの形式は定義ファイル.defを使わない形式、declspec(dllexport)を使う形式の方です。  呼び出し側はVC6.0EnterPrize(SDK)を使います。 (諸事情により6.0以上にUPすることは不可能)     まず、静的リンクをし、関数を呼び出してみました。  (設定のリンクよりlibをリンクさせ、ヘッダをインクルードして)  すると以下のメッセージが出てしまいます。 リンク中... Dialog1.obj : error LNK2001: 外部シンボル ""__declspec(dllimport) void __cdecl Init(unsigned char *,unsigned char *,unsigned char *,unsigned char *)" (__imp_?Init_Card@@YAXPAE000@Z)" は未解決です Debug/CardMake.exe : fatal error LNK1120: 外部参照 1 が未解決です 。 link.exe の実行エラー    色々やってみましたが、このエラーから回避できませんでした。  ヘッダ自体に #ifdef _USRDLL #define DLL_PORT __declspec(dllexport) #else #define DLL_PORT __declspec(dllimport) #endif    の宣言があるので、別に特別なことをしなくても、大丈夫そうなのですが、何故か出来ません。  次に動的リンクを行っていました。  するとLoadLibraryでエラーになり、GetLastErrrorで14001(エラーメッセージはつかめず)が返ってきました。 (色々調べたところ定義ファイルがないと動的リンクはできないようですね)    というわけでにっちもさっちも行かなくなった状況です。  そこでご質問です。 (1)定義ファイルを使わない形式のライブラリ(暗示的に定義されているもの)はどのように呼び出させばよいでしょうか? (2)2005のライブラリを6.0から呼び出すことは可能ですか?  また呼び出す方法は?  すいませんがご回答をお願いします。

専門家に質問してみよう