DLLを作成しています。
クラスのエクスポートをしようとしています。
エクスポートをしたいのですが、
エクスポートしたいクラスのメンバには、
stl::listや、stl::vectorが含まれています。
クラスをエクスポートするときは、
エクスポートしたいクラスの基底クラスや、
そのメンバになっているクラスも
エクスポートしなければならないため、かどうか
現状ではwarning C4251が出ます。
(STLなどが含まれていないクラスはエクスポートできています)
しかし、stl::listや、stl::vectorは、
VC付属のものですので、ヘッダを変更することができません。
エクスポートのためのDEFファイルもありません。
(そもそも、クラスエクスポートの際のDEFの記述がどうなるのかわかりません)
どうすればよいでしょうか。
CランタイムライブラリにはDLL版がありますけど、STLにはないのでしょうか。
テンプレートの性質上DLLにはなじまないのかもしれませんが……。
設計上、エクスポートしたいクラスにSTLが入っていること自体がおかしいのかもしれません。
その場合はどういった手段が考えられますでしょうか。STLを除くしかないでしょうか。
何かヒントがあれば、
どんなものでも良いので、
よろしくお願いします。
クラスの export は __declspec(dllexport) でする。定義ファイルはつかわない。
STL(テンプレート)でも、bindされたものはテンプレート宣言をかいてそこに export を指定すればいい。
テンプレート自体の export はサポートしてる処理系がほぼないから規格上許可されても現実的に無理。
MSDNでATLについて調べるとSTLコレクションを使うための技術説明がある。参考にするといい。(ATL、STLなどで検索しよう
楽園さんありがとうございます。
テンプレート宣言を書くと確かに警告が出なくなりましたが、std::listが依存しているクラスがたくさんあって、それらも全部宣言しなければならないようで、まだ警告が出ないところまで行っていません。がんばります。
あと、MSDNをATL、STLで調べるといろいろ出てきました。たくさん知らない言葉が出てきて大変です。がんばります!
私のほうにも勘違いなどありましたので
一応私のしたいことをもう少し具体的に補足します。
・したいのは、STLを含むクラスのエクスポートです。
・DLL利用側も、DLL側も、全ソースコードが私の管理下にあります。
・DLL利用側に基底クラスがあります。このクラスは純粋仮想関数のみを含むクラスです。
・そのクラスをDLL側で派生させたクラスをエクスポートしたいと思っています。
・実際にexportしたい(DLL利用側で使用したい)のは、そのクラスの生成関数と、DLL側でオーバーライドしたpublicメソッドのみです。STLはクラスのprivateメンバだからDLL利用側では使用しません。メソッドはvtblから呼び出されるでしょうから、要はSTLを無視できれば良いのでは? と思っています。だから、まったく問題の解決にはなっていませんが、C4251警告を無視すればよいだけかなぁ、と思っています。
関係ありそうなところ
http://www.tietew.jp/cppll/archive/8444
ここでは、クラス全体に _declspec(dllimport) を付けず、メソッドごとにつけておられますね。
上記投稿修正します。
誤 _declspec(dllimport)
正 _declspec(dllexport)
続報です。
http://forums.belution.com/ja/vc/000/116/93s.shtml
warningを出さないようにすればよいよという意見。
http://www.hey-to.net/ML-archive/vcppML/2000/msg07943.html
テンプレート宣言すればよい、というご意見。
これは楽園さんと同じご意見ですね。
なぜ私はテンプレート宣言がうまくいかないのか……。
http://www.hey-to.net/ML-archive/vcppML/2000/msg08073.html
ポインタにすればよいよという意見。
ラッパクラス作るにしても宣言は公開するわけですし、結局はポインタって事ですよね。vectorとかをnewしたことないんですけど……。まあ、できそうではあります。
http://support.microsoft.com/kb/q168958/
「STL オブジェクトであるデータ メンバが含まれるクラスをエクスポートする方法」
ってそのものずばりありますよ!
「現在エクスポートできる唯一の STL コンテナは vector です。そのほかのコンテナ (つまり、map、set、queue、list、deque) にはすべて、ネストしたクラスが含まれており、エクスポートすることはできません。」
ええっ……。そんな……。
なるほど、vectorのテンプレート宣言はうまくいくようですね。
listがだめなのか……。listが入ってるんですけど……。だめでしょうか……。
ポインタにしようかな……。
How To Exporting STL Components Inside & Outside of a Class
.............................
APPLIES TO
• Microsoft Visual C++ 5.0 Enterprise Edition
• Microsoft Visual C++ 6.0 Enterprise Edition
• Microsoft Visual C++ 5.0 Professional Edition
• Microsoft Visual C++ 6.0 Professional Edition
• Microsoft Visual C++ 6.0 Standard Edition
VC.NET2003ならどうだろう?
(STLは.NET以前/以降で、templete 対応のため大変更されてます)
一縷の望みさん補足ありがとうございます。
VC.NET2003でも同じでした。警告出ます。
一応vectorはテンプレート宣言を書くと警告は出なくなります。
template class __declspec(dllexport) std::vector<int>;
extern template class __declspec(dllimport) std::vector<int>;
listは
#pragma warning(disable:4251)
#pragma warning(default:4251)
で該当部分を囲んで警告が出ないようにしました。
特に問題はなく動いています。
解決としてよいのかどうかわかりませんが
こんなところです。
助言くださった方々、ありがとうございました。
ツイート | ![]() |