1

最初に質問を示し、次に背景の詳細​​を示します。

私の質問

  1. DLLモジュールでグローバルオブジェクトを定義するのは良い考えですか?
  2. とにかく、ホストプログラムでmain()関数が呼び出される前に、DLLモジュールのグローバルオブジェクトが構築されていることをどのように確認する必要がありますか?

バックグラウンド

私はWindowsプラットフォーム上のVisualC++プロジェクトに取り組んでいます(しかし同時に、Linuxをサポートするためにソースコードのクロスプラットフォーム機能を保証する必要があります)。

私の同僚の1人は、他のプロジェクトで共有できるスタンドアロンDLLモジュールを設計および実装するように依頼されました。彼は、目的の異なる2つのDLLを開発することを計画しました。

  1. DLL#1-簡略化されたCOMのように見えるインターフェイスマネージャモジュール。このDLLには、ユーティリティクラスのすべてのファクトリを管理するC++クラスが含まれます。
  2. DLL#2-すべてのユーティリティクラスとそれに対応するファクトリクラスのコンテナ。

そのような設計に関する彼の考慮事項は次のとおりです。

  1. COMはクロスプラットフォーム対応ではありません。その上、COMは私たちのプロジェクトの状況には少し複雑すぎるので、彼はこの簡略化されたCOMライブラリを設計しました。
  2. 彼は、この簡略化されたCOMライブラリは完全に独立しており、「XMLパーサー」などのユーティリティクラスと混合すべきではないと考えているため、すべてを1つのDLLに入れるわけではありません。そして、私はこの点に同意します。
  3. すべてのユーティリティクラスには、対応するファクトリクラスがあります。私の同僚は、DLL#2の.cppファイルで各ファクトリクラスのグローバルオブジェクトを定義し、それらをSimplifiedCOMライブラリに登録できるようにするためのトリッキーなコードを記述しています。彼の意図は次のとおりです。グローバルオブジェクトは、ホストプログラムのmain()関数が呼び出される前に構築する必要があり、構築中に、ホストプログラムがユーティリティクラスのインスタンスを作成できるように、SimplifiedCOMに登録されます。 main()に入ります。この動作はCOMと非常によく似ています。私はこの点に同意しますが、「私の質問」のセクションで述べたように、私の質問も発生します。

実際、いくつかの実際のテストで、これらのグローバルオブジェクトを意図したとおりに構築できなかったことがわかりました。これは、悲しいことに、彼の心を傷つけます;-)。しかし、彼のデザインはまだ見栄えが良いと思うので、それを機能させる方法を見つけたいと思います。これらのDLLは、次のように使用することをお勧めします。DLLは、libsおよびincludesを使用して開発者のコ​​ンピューターにデプロイされます。次に、具体的なVC ++プロジェクトに、リンク時に組み込まれます。現在、コンパイルエラーやリンクエラーは発生していませんが、DLL#2のこれらのグローバルオブジェクトだけが希望どおりに作成されていません。

4

1 に答える 1

1

DLLのDllMain()関数を使用してすべてを初期化することはできませんか?を確認するDLL_PROCESS_ATTACHだけで、DLLが現在ロードされているかどうかがわかります。同様に、を使用DLL_PROCESS_DETACHして任意のクリーンアップを実行できます。

Linuxで物事を開いたままにしている場合は、GCCを使用することもできます__attribute__((constructor))

あなたの質問に関して:

  1. 実行可能ファイルでグローバルを使用するのは良い考えです。それが「良い」アイデアであるかどうかは完全に主観的です。私は個人的にグローバルを可能な限り避けています。それは物事を単純化するからです(スパゲッティコードが少ない、パラメーターとして参照/オブジェクトを渡すと依存関係が明確になる、スレッドの問題が少ないなど)。私はあなたのユースケースを完全に理解していないので、はっきりとした「はい」または「いいえ」を与えることはできません。例が役立ちます。
  2. 関数の前に作成する必要がある理由がわかりませんmain()DllMain()DLL内の他の関数の前に呼び出される(そしてユーザーはそれを呼び出さない、OSは呼び出す)で作成されることを保証できる場合でも、本当に前にある必要がありmain()ますか?びっくりします。
于 2012-11-25T16:22:41.930 に答える