VC6SP6 Windows XP
最近、スタティックライブラリの使い方を覚えたのですが、
わからないことがあるので教えて頂きたいです。
お願いします。
現在、ダイアログベースのアプリで、以下の自作クラスを使用しています。
CUtitity (基本クラス:なし)
CEditEx (基本クラス:CEdit)
CListBoxEx(基本クラス:CListBox)
CStaticEx (基本クラス:CStatic)
上記4つをスタティックライブラリで作成したいのです。
CUtitityはスタティックライブラリで作成し、関数の実体と宣言をコピーして
メインアプリでライブラリをリンクし、ヘッダをインクルードすることで
今までどうり使用することができました。
しかし、その他3つのクラスは基本クラスから派生させて作成したクラスです。
スタティックライブラリのプロジェクトで、
挿入 ⇒ クラスの新規作成 ⇒ 派生元をCEditにして作成すると以下のダイアログが
表示されます。
「新しいクラスウィザードは基本クラスCEditに対してインクルードするための適切なヘッダーファイルを見つ
けることができませんでした。クラスから派生するために選択した場合、手動で適切なヘッダ
ーファイルを\***\EditEx.hへ追加する必要があります。」
これはCEditが宣言してあるヘッダーファイルをCEditEx.hでインクルードしろ!ということだ
と思うのですが、そのヘッダーファイルの名前がわかりません。
C:\Program Files\Microsoft Visual Studio\VC98\Include
の中でそれらしきヘッダーファイルを探したのですがよくわかりません。
知っている方いましたら教えて頂きたいです。
宜しくお願いします。
CEditEx
という派生クラスを作るときにおそらく
EditEx.h
EditEx.cpp
という二つのファイルが作成されます。
ですので、
>C:\Program Files\Microsoft Visual Studio\VC98\Include
>の中でそれらしきヘッダーファイルを探したのですがよくわかりません。
にはなく、デフォルトであればワークスペースがあるディレクトリに
EditEx.h
があるはずです。
こんちわ
MFCライブラリ リファレンスによりますと
CEditの必要条件 ヘッダー:afxwin.h
とあります
これインクルードすればCEditクラス自体は認識されると思います
あ、すみません勘違いしていました。orz
私の発言は無視してください。
afxwin.h
をインクルードしただけでできました。
ありがとうございます。
クラスをスタティックライブラリに変更して、正常動作を確認できたので、
その他のクラスもスタティックライブラリにしようと考えています。
例えば、
CommandLib.libの中に
CAiCmd、CAtCmd、CArCmdとあるとします。
TransactionLib.libの中に
CArcTxRx、Cxxx、・・・とあるとします。
TransactionLibのプロジェクトでCArcTxRxを作成するときに、
CArcTxRxでは、CommandLib.lib内のCAiCmd、CAtCmd、CArCmdの3つのクラスを使用しま
す。
この時にCAiCmd、CAtCmd、CArCmdを使用するためにはヘッダーファイルをインクルードする必
要があると思うのですが。
この場合、TransactionLibのプロジェクトにCommandLibのプロジェクトから各クラスのヘッダーファイル
を持ってくる必要があるのでしょうか?
どのようにしてリンクさせるのか教えて頂きたいです。
CArcTxRxでCAiCmd、CAtCmd、CArCmdを使用したいなら当然ヘッダは必要だと思います。
ですが、TransactionLibフォルダに 上記の3クラスのヘッダファイルを持ってきてしまうと
3クラスの内容を変更したときなど、バージョンの管理がとても面倒になると思います
一般的な方法としましては、普通にTransactionLibのプロジェクトから
CommandLibのフォルダを参照します
そうすることによって CommandLibの内容を変更してもきちんと最新を使用する
ことができると思います。
参照方法は・・#includeのところで パス(絶対パスor相対パス)で見に行かせるか
プロパティ?か何かのとこで参照するパスを設定できるのでそこで設定してください
> プロパティ?か何かのとこで参照するパスを設定できるのでそこで設定してください
VC++6.0なのでプロジェクトの設定のC++/Cのタブを選択して
カテゴリをプリプロセッサにすると追加のインクルードパスと言うのが
あると思いますのでここにライブラリのヘッダーファイルがあるパスを入れておけば、
#Include文でパスを指定しなくてもヘッダーファイルの参照が可能になります。
ツールのオプションでディレクトリのタブに設定する事も出来ますが、
ここはプロジェクトに共通して使用するパスを設定するべき場所なので
プロジェクト特有の設定はここに入れないほうが良いと思います。
ライブラリも同一ワークスペースに入れておくと設定をある程度簡略化できます。
他のプロジェクトにも流用したいような場合は別ワークスペースにしておいた方が
管理しやすいかもしれません。
>VC++6.0なのでプロジェクトの設定のC++/Cのタブを選択して
>カテゴリをプリプロセッサにすると追加のインクルードパスと言うのが
>あると思いますのでここにライブラリのヘッダーファイルがあるパスを入れておけば、
>#Include文でパスを指定しなくてもヘッダーファイルの参照が可能になります。
CommandLibプロジェクト内のクラス「CBs」で
下記ヘッダーをインクルードしているので、以下のようにパスを入れましたが、
「../CommPortLib/CommPort.h ../ExtensionLib/ListBoxEx.h」
error C2061: 構文エラー : 識別子 'CListBoxEx' がシンタックスエラーを起こしました。
などのエラーがでてしまいます。
スタティックライブラリーを使う側でも、
スタティックライブラリーを作る時に使った
「STDAFX.H STDAFX.CPP」を使えばうまくいくと思いますが......
スタティックライブラリーを使う利点は、
「MFCXX.DLL」なくても実行できる。
だと思いますが..........
>スタティックライブラリーを使う側でも、
>スタティックライブラリーを作る時に使った
> 「STDAFX.H STDAFX.CPP」を使えばうまくいくと思いますが......
すいません、言ってる意味が理解できないのですが・・・
CommandLibとCommPortLibとExtensionLibは三つともスタティックライブラリです。
それぞれのプロジェクトに「STDAFX.H STDAFX.CPP」はありますが・・・
> 「STDAFX.H STDAFX.CPP」を使えばうまくいくと思いますが......
使うとはどういう意味ですか?
もう少し詳しく説明します。
スタティックライブラリで新規プロジェクト「CommandLib」を作成しました。
これに「CBs」というジェネリッククラスを作成しました。
bs.cppではstdafx.hとbs.hしかインクルードしていません。
bs.hでCListBoxEx* m_pLB;というメンバ変数を宣言しています。
今、この型がわからないというエラーが出ています。
CListBoxExという型は、別のスタティックライブラリプロジェクト「ExtensionLib」で
作成したクラス「CListBoxEx(CCListBoxが基本クラス)」のクラスです。
「CommandLib」プロジェクト内のクラス内で「ExtensionLib」のクラスを使いたいというこ
とです。
つばさ 2007/03/23(金) 13:30:46
PATIO 2007/03/23(金) 14:33:11
で示された通りやってみたのですが、どれもできません。
やりかたが意図したものと違うのかもしれません。
もうちょっと具体的に教えていただけないでしょうか?
例をあげて説明してもらえると助かります。
えーっと
自作されたCListBoxEx というクラスも
元々ある CListBoxやC~とかいうMFCクラスも
特に使用方法に違いはありませんので
普段MFCのクラスを使用してるのと同じようにCListBoxExが定義されている
ヘッダ、ライブラリをきちんと読み込むようにだけすれば
問題なく使用できるはずですが;
スタティックリンクライブラリの場合、ライブラリを使用するアプリケーションの方に
関連するライブラリが全てリンクされていれば良いはずです。
各スタティックリンクライブラリは特にリンクの必要が無かったと思います。
そこがクリアできていれば、この記述は釈迦に説法ですが。
ヘッダーファイルに関してはそのクラスなり関数を使用する為の宣言がほしいだけなので
原則的には使うそのクラスを使用するヘッダーファイルやソースファイルに
インクルードしていればいいだけの話です。
この場合、追加のインクルードパスを設定するのはライブラリを使用する側のプロジェク
トになります。
ライブラリ側のプロジェクトに設定しても意味がありませんよ。
使用する側のプロジェクトと同一フォルダ内にヘッダーファイルが存在しないから
ヘッダーファイルが存在するパスを予めプロジェクトに指定しておく事で
コンパイラがファイルを探す事ができるようにするのがプロジェクトの追加の
インクルードパスの目的です。
この辺は、それぞれ何の為にしなくてはいけないのかと良く考えてみてください。
目的がわかれば、自ずと何処に設定する必要があるのかわかるはずです。
>bs.cppではstdafx.hとbs.hしかインクルードしていません。
>bs.hでCListBoxEx* m_pLB;というメンバ変数を宣言しています。
>今、この型がわからないというエラーが出ています。
全ての型はそれを宣言しているヘッダを読み込んでから使いましょうね。
>スタティックリンクライブラリの場合、ライブラリを使用するアプリケーションの方に
>関連するライブラリが全てリンクされていれば良いはずです。
補足させてもらいます。
スタティックライブラリは、アプリケーションをリンクする段階で必要なものが全てリン
カに指定されていればいいです。
指定方法には、オブジェクトファイルにリンク指定を埋め込む場合と、リンカに直
接リンク指定を渡す方法があります。
プロジェクト設定からはリンカに渡す設定が編集でき、ソースコードのPragmaで
指定するとオブジェクトファイル中に指定を埋め込めます。
MFC以外の場合も、参照するヘッダをインクルードして、そのファイルをリンクする
際に参照したライブラリを指定します。
MFCクラスから派生するクラスや、MFCの機能を利用する場合は、MFCのヘッダ
をインクルードするファイルにPragmaを埋め込んだほうが指定ミスは少ないと思い
ます。
プロジェクトで設定する場合は、リンクするオブジェクトファイルが必要としているラ
イブラリを全て探して手作業で埋め込み、使用するライブラリが変わるたびに影
響する全ての設定をこれまた手作業で直す作業が必要です。
返事遅くなりました。
出張などでバタバタしていたもので・・・
>オリバ 2007/03/27(火) 23:59:09
上の記述で、
bs.h内で
#include ../ExtensionLib/ListBoxEx.h
をインクルードすれば「CommandLib」でリビルドすればエラーはなくなりました。
しかし、この「CommandLib.lib」を使う側のプロジェクト「MainPjct」では、
「Debug」「Release」フォルダ内に「CommandLib.lib」をコピーします。
そして、「MainPjct」の直下に「command」、「extension」という名前でフォルダを作
成し、それぞれのフォルダの直下に各ライブラリのヘッダーファイルをおいています。
そうすると、../ExtensionLib/ListBoxEx.hなどのパスが変わるのでリビルドするとエ
ラーになります。
この場合、bs.h内のインクルード文のパスを変更してもよいのでしょうか?
また、ダメなのであればどうするべきですか?
>指定方法には、オブジェクトファイルにリンク指定を埋め込む場合と、リンカに直
>接リンク指定を渡す方法があります。
これは知らなかったです。
>オブジェクトファイルにリンク指定を埋め込む場合
この使い方がいまいちわかってなかったです。
両方やっても、「リンカに直接リンク指定を渡す方法」だけでも同じだったので
プラグマ指定は意味あるの?っと思っていました。
そこで質問があります。
「CommPortLib」というスタティックライブラリのプロジェクトがあります。
出力されるライブラリは「CommPort.lib」です。
そのプロジェクトのCommPort.hの先頭で、
#pragma comment(lib,CommPort.lib)
と記述しました。
「CommPort.lib」を使う側のプロジェクト「MainPjct」の「Debug」「Release」フォルダ内
に「CommPort.lib」をコピーします。
そして、リビルドすると、
リリースのほうは通るのですがデバッグのほうで
LINK : fatal error LNK1104: ファイル CommPort.lib を開けません。
というエラーがでます。
パスがあっていないからだと思い、
CommPort.hで、以下のように記述を変更したら問題なくリビルドとおりました。
#ifdef _DEBUG
#pragma comment(lib,Debug/CommPort.lib)
#else
#pragma comment(lib,Release/CommPort.lib)
#endif
しかし、これはライブラリを使う側の「MainPjct」の直下にヘッダーがあり、
「Debug」「Release」フォルダ内に「CommPort.lib」があるとき限定だと思います。
どうすればいいのでしょうか?