プロジェクトで暗黙的なリンクを使用したいのですが、nmake は実際には .def ファイルを必要としています。問題は、これがクラスであり、エクスポート セクションに何を書くべきかわからないことです。誰かが私を正しい方向に向けることができますか?
エラー メッセージは次のとおりです。
NMAKE : U1073: 'DLLCLASS.def' の作成方法がわからない
PS: Windows CE Platform Builder を使用してビルドしようとしています。
プロジェクトで暗黙的なリンクを使用したいのですが、nmake は実際には .def ファイルを必要としています。問題は、これがクラスであり、エクスポート セクションに何を書くべきかわからないことです。誰かが私を正しい方向に向けることができますか?
エラー メッセージは次のとおりです。
NMAKE : U1073: 'DLLCLASS.def' の作成方法がわからない
PS: Windows CE Platform Builder を使用してビルドしようとしています。
私の記憶が正しければ__declspec(dllexport)
、クラスで使用でき、VC++ はクラスに関連するすべてのシンボル (コンストラクター/デストラクタ、メソッド、vtable、typeinfo など) のエクスポートを自動的に作成します。
Microsoft は、これに関する詳細情報をここに持っています。
抽象工場であることが最善の方法であることがわかりました。
純粋な仮想基本クラスを定義することから始めます。これは実装のないクラスであり、純粋な仮想インターフェイス クラスです。
この仮想ベースの「抽象インターフェイス」クラスをエクスポートできますが、そうする本当の理由はありません。呼び出し元がそれを使用する場合、ポインター (PImpl、または実装へのポインター) を介してそれを使用するため、呼び出し元が知っているのは単純なメモリ アドレスだけです。Def ファイルは、最新の状態を維持するために少々手間がかかりますが、__declspec(dllexport) が達成できる以上の利点を提供します。どのような利点がありますか?私たちはそれに着きます、あなたはただ待ってください。
実際のクラスが仮想ベースからパブリックに継承されるようにします。次に、オブジェクトを構築するためのファクトリ メソッドと、クリーンアップを実行するための " release " っぽい呼び出し可能なデストラクタを作成します。これらのメソッドに「 ConstructMyClass」や「ReleaseMyClass 」などの名前を付けます。「 MyClass 」を置き換えてください:-)
これらのファクトリ/リリース メソッドは、パラメータが必要な場合は POD タイプのみを使用する必要があります (plain-old-data: integer、char など)。戻り値の型は、仮想抽象インターフェイスの基本クラス、またはそれへのポインターである必要があります。
IMyClass* CreateAnObjectOfTypeIMyClass();
仮想基本クラスが必要な理由が明らかになったのではないでしょうか? 仮想インターフェイス クラスには実装がないため、基本的にすべて POD 型 (並べ替え) であるため、クラスの「データ型」は、Visual Basic、C、または非常に異なる C++ コンパイラなどのほとんどの呼び出し元で理解できます。
あなたが十分に気の利いた人なら、「手動リリース」方法の必要性を回避することができます (申し訳ありませんが、そうしなければなりませんでした)。どのように?スマート ポインターと pImpl タイプのアーキテクチャを使用してクラス内の独自のリソースを管理し、オブジェクトが停止したときにそれ自体がクリーンアップされるようにします。そうすることは、私たちの聖人であり救世主であるScott Meyersの不滅の言葉を借りれば、コーラーがクリーンアップの必要性を無視できるようにすることで、 「正しく使用するのは簡単で、間違って使用するのは難しい」ということを意味します。「 .close 」と呼ぶことを決して忘れたことのない私たちの中で、最初の石を投げましょう。
たぶん、このアーキテクチャはおなじみのように聞こえますか? 基本的には、COM のマイクロマシン バージョンです。少なくとも、インターフェイス、ファクトリの構築、およびリリースの概念については、まあまあです。
最後に、クラスのインターフェイスをエクスポートし、 CreateメソッドとDestroyメソッドを作成(およびエクスポート) しました。呼び出し元は、 PleaseConstructMyClassファクトリ関数を呼び出して、完全に構築され、完全に実装され、完全にベイクされたオブジェクトを偽装して DLL に返すことができます。そのインターフェースの。クラスのすべてのパブリック メソッド (少なくとも抽象仮想インターフェイス内のメソッド) を呼び出して、楽しいことをすべて実行できます。
ファクトリ関数によって返されたオブジェクトの処理が終了したら、「 ReleaseMyClass 」関数を呼び出して DLL にオブジェクトのリソースをクリーンアップするように依頼するか、クラス自体をクリーンアップすることでそれらを支援することができます。 「ReleaseMyClass」メソッドは冗長で役に立ちません。
誰かが Def ファイルとインターフェイスを使用することによる特定の利益とトレードオフに興味を持っている場合 (私の盲目的な発言は別として)、パイプを鳴らしてください。より深く掘り下げることができます。
あなたはこのようなものを愛していませんか?
dumpbin /symbols myclass.objを使用すると、メンバー関数の装飾名をいつでも見つけることができます。
私の場合
class A {
public:
A( int ){}
};
dumpbin
ダンプはシンボルを示しました??0A@@QAE@H@Z (public: __thiscall A::A(int))
このシンボルを .def ファイルに入れると、リンカーはエクスポート シンボルに A::A(int) シンボルを作成します。
しかし!@paercebal がコメントで述べているように、装飾された (マングルされた) 名前を手動で入力するのは面倒です。エラーが発生しやすく、悲しいことに、コンパイラのバージョン間での移植性が保証されていません。
解決策は次のとおりです。
クラスがエクスポートされるため、エクスポートされたメソッドを .def ファイルに追加する必要もあります
コンストラクタをエクスポートする方法がわからなかったので、オブジェクトの新しいインスタンスを返すファクトリ メソッド ( static ) を使用しました。
他の関数は、.def ファイルに通常のエクスポート宣言を追加することによってエクスポートされます
誰かがこの情報から恩恵を受けることを願っています.