3

モジュール/共有オブジェクト/DLL を使用して実行時に拡張できる C でアプリケーションを作成しています。これらのモジュールは既存のプログラムの API を使用する場合がありますが、後でロードされるモジュールで使用するための新しい関数を提供する場合もあるため、モジュールが相互に依存関係を持つ可能性があります。

Linux での私の現在のアプローチは、すべてのモジュールが依存する他のモジュール名のリストを返す depends() 関数を定義することです。そうすれば、すべてのモジュールをそれ自体でコンパイルおよびリンクし、モジュールを dlopen() およびRTLD_LAZYでロードし、最初にその依存関係を解決してから、 で完全にロードすることができRTLD_GLOBALます。これはうまく機能し、まさに私が望むことを行います。また、モジュールに依存する他のすべてのモジュールを再コンパイルすることなく、モジュールを別のバージョンに置き換えることもできます。

実際の問題は、これを Windows に移植するときに発生します。まず、すべての依存関係のエクスポート シンボル テーブルを既に提供していない DLL をリンクする方法を見つけられませんでした。私が見落としているものはありますか?

第 2 に、Windows API の LoadLibraryEx は遅延読み込みを実行できないようです。これは、依存関係を処理するのではなく、先に進み、参照されるすべての DLL 自体を読み込む前に返すためです。将来、実際にモジュールをロードする前にバージョンチェックも実行したいので、これは私が望むものではありません。この動作を回避する方法はありますか?

3 つ目の奇妙な点は、DLL に依存する他のすべてのモジュールを再コンパイルしないと、DLL を置き換えることができないことです。実際に動作することもありますが、通常は異常事態が発生したり、プログラムのセグメンテーション違反が発生したりします。

Windows でそのようなモジュラー アプリケーションを作成することは可能でしょうか? どんな提案や異なるアプローチも大歓迎です!

更新:私のモジュールがLinuxでお互いの機能をどのように使用するかを明確にするために(Windowsでも同様にしたい):すべてのモジュールは、記述された依存関係から関数を呼び出したい別のモジュールの名前を返すだけです() 関数とそのヘッダーをインクルードし、使用された関数をコード内でラップせずに直接呼び出します。これが機能するのは、Linux では共有オブジェクトのリンク時にすべてのシンボルを解決する必要がないためです。

4

1 に答える 1

4

すべての関数を手動で ( を使用して) エクスポートし、 を__declspec(dllexport)使用してロードすることができますGetProcAddress。この場合、各関数のシグネチャを知る必要があり、C 関数のみに限定されますが、これは機能します。両方のモジュールをコンパイルすると、C 関数も C++ クラスを返すことができます。これについては後で詳しく説明します。GetProcAddress&を使用するとLoadLibrary、モジュールが完全に独立します。基本的には手動でリンクを行っていますが、これは Linux で行っていることですよね?

LoadLibaryライブラリが依存しているライブラリのみをロードするため、相互に依存してロードしないようにしてください。それらは本当に独立しているか、そうでないかのどちらかです。適切に行われた場合、1 つのライブラリを変更しても、他のライブラリが強制的に再コンパイルされることはありません (それらを一緒にリンクしないため)。

COM のようなものを使用することをお勧めします。そのため、個々の関数ではなく、各ライブラリがインターフェイスを返すようにします。そうすれば、単純に DLL 全体をロードし、それらを簡単にリンクすることもできます (DLL を渡す -> オブジェクトを渡す)。XPCOM と COM を調べると、実際には非常に簡単に実行できます。

于 2009-07-25T12:30:00.530 に答える