DLL C++ クラスのエクスポート、.def ファイルに関する質問
-
06-07-2019 - |
質問
私はプロジェクトで暗黙的リンクを使用したいのですが、nmake は実際には .def ファイルを必要としています。問題は、これがクラスであり、エクスポート セクションに何を書けばよいのかわからないことです。誰か私に正しい方向を教えてくれませんか?
エラーメッセージは次のとおりです。
Nメイク:U1073:「DLLCLASS.def」の作り方がわかりません
追伸:Windows CE Platform Builder を使用してビルドしようとしています。
解決
dumpbin / symbols myclass.obj
私の場合
class A {
public:
A( int ){}
};
dumpbin
ダンプはシンボル ?? 0A @@ QAE @ H @ Zを示しました(public:__thiscall A :: A(int))
このシンボルを.defファイルに挿入すると、リンカーはエクスポートシンボルにA :: A(int)シンボルを作成します。
しかし! @paercebalがコメントで述べているように:装飾(マングル)名の手動入力は面倒です-エラーが発生しやすく、悲しいことに、コンパイラバージョン間での移植性は保証されません。
他のヒント
正しく思い出せば、 class で __ declspec(dllexport)
を使用できます。VC++は、クラスに関連するすべてのシンボル(コンストラクタ/デストラクタ、メソッド、vtable、typeinfoなど)。
Microsoftには、このこちらに関する詳細情報があります。 。
私は抽象工場になるための最良のルートを見つけました。
まず、純粋に仮想的な基本クラスを定義します。これは実装のない、純粋な仮想インターフェイス クラスです。
この仮想ベースの「抽象インターフェイス」クラスをエクスポートできますが、そうする本当の理由はありません。呼び出し元がこれを使用するときは、ポインタ (PImpl、または実装へのポインタ) を介してそれを使用するため、呼び出し元が知っているのは単純なメモリ アドレスだけです。Def ファイルは、維持するのに少し手間がかかりますが、__declspec(dllexport) が達成できる以上の利点を提供します。どのようなメリットがあるのでしょうか?すぐに解決しますので、お待ちください。
実際のクラスを仮想ベースからパブリックに継承させます。次に、オブジェクトを構築するためのファクトリ メソッドを作成します。リリース「クリーンアップを実行するための呼び出し可能なデストラクターのようです。これらのメソッドに「」のような名前を付けます。ConstructMyClass" そして "ReleaseMyClass」。交換してください」私のクラス" :-)
これらのファクトリ/リリース メソッドは、パラメータが必要な場合は POD タイプのみを取る必要があります (plain-old-data:整数、文字など)。戻り値の型は、仮想抽象インターフェイスの基本クラス、つまりそれへのポインタである必要があります。
IMyClass* CreateAnObjectOfTypeIMyClass();
おそらく、仮想基底クラスが必要な理由が明らかになったのではないでしょうか?仮想インターフェイス クラスには実装がないため、基本的にすべて POD タイプ (一種) であるため、クラスの「データ型」は、Visual Basic、C、または非常に異なる C++ コンパイラなどのほとんどの呼び出し元で理解できます。
十分に凝っている場合は、「」の必要性を回避できます。手動リリース" メソッド (申し訳ありませんが、そうする必要がありました)。どうやって?スマート ポインターと pImpl タイプのアーキテクチャを通じてクラス内の独自のリソースを管理することで、オブジェクトが終了すると、オブジェクト自体がクリーンアップされます。そうすることは、私たちの聖人であり救い主の不滅の言葉を借りれば、あなたの階級が スコット・マイヤーズ」正しく使うのは簡単、間違った使い方は難しい" 発信者にクリーンアップの必要性を無視させることによって。私たちの中で、「」と呼ぶことを決して忘れなかった人はそうしましょう。。近い「最初の石を投げます。
このアーキテクチャには見覚えがあるかもしれません?それもそのはず、基本的には COM のマイクロマシン版です。そうですね、少なくともインターフェース、ファクトリーの構築、リリースのコンセプトはあります。
最終的に、クラスのインターフェイスをエクスポートし、作成(そしてエクスポート)しました。 作成する そして 破壊する メソッドを呼び出し、呼び出し元がメソッドを呼び出せるようになりました。 MyClass を構築してください Factory 関数を使用すると、DLL はインターフェイスを装って、完全に構築され、完全に実装され、完全にベイクされたオブジェクトを返すようになります。これらはクラスのすべてのパブリック メソッド (少なくとも抽象仮想インターフェイス内のメソッド) を呼び出して、あらゆる楽しいことを実行できます。
ファクトリ関数によって返されたオブジェクトの処理が完了したら、「ReleaseMyClass" 関数を使用して、DLL にオブジェクトのリソースをクリーンアップするように依頼するか、クラス自体をクリーンアップして "ReleaseMyClass" メソッドは冗長で役に立ちません。
Def ファイルとインターフェイスを使用することによる具体的なメリットとトレードオフに興味のある方がいらっしゃいましたら (私の盲目的な言い分は別として)、ぜひお声がけください。さらに詳しく掘り下げることができます。
こういうのが好きなだけじゃないの?
解決策は次のとおりです:
-
クラスがエクスポートされるため、エクスポートされたメソッドを.defファイルに追加する必要もあります
-
コンストラクタをエクスポートする方法を見つけられなかったため、オブジェクトの新しいインスタンスを返すファクトリメソッド(static)を使用しました
-
その他の関数は、.defファイルに通常のエクスポート宣言を追加することによりエクスポートされます
この情報から誰かが利益を得ることを願っています。