あなたは非常に初歩的なことを求めているわけではありません。Windows は単にあなたが望むものをサポートしていません。
この問題を回避するには、いくつかのオプションがあります。
- 2 つの DLL を作成します。必要な他の dll に対して静的にリンクするプラグイン実装 dll。そして、ホスティング アプリによって読み込まれる単純な「ファサード」DLL です。ファサード dll は、SetDllDirectory を呼び出してから LoadLibrary を呼び出して、実装 dll に必要な検索パスをロードします。次に、プラグインのエクスポートされた関数ごとに、GetProcAddress を使用して呼び出しを実装 dll に直接渡すスタブ関数を実装します。
プラグイン インターフェイスが複雑で、使用している dll インターフェイスがそうでない場合:
あきらめて、LoadLibrary (明示的なパスを指定) と GetProcAddress を使用して、サテライト dll の機能にアクセスします。痛み。
最後のオプションは、最も文書化されておらず、Windows プログラマーに最もよく理解されていません。基本的に、.NET: Side by Side アセンブリをサポートするために構築されたテクノロジの Windows バージョンを使用します。怖がらないでください。「サイド バイ サイド アセンブリ」は非常に単純な通常の古い dll ですが、それに関する追加情報を提供する .manifest ファイルが付随しています。
これを行う理由は、SxS テクノロジを介してリンクされている dll の検索順序が通常の dll 検索順序と異なるためです。つまり、c:\windows\WinSxS を検索した後、windows は同じフォルダーを検索します。 exeのフォルダーではなく、dllを参照するdll。
まず、プラグイン dll がリンクする必要があるすべてのサテライト dll のインベントリを取得し、それらから「アセンブリ」を作成します。つまり、多数の file= ノードを含む .manifest ファイルを作成します。アセンブリに名前を付ける必要があります。「MyAssembly」と呼びましょう。
次のような内容で、dll のフォルダーにファイル "MyAssembly.manifest" を作成します (含める必要がある各 dll をリストします)。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="MyAssembly" processorArchitecture="*" type="win32" version="1.0.0.1"/>
<file name="firstrequireddll.dll"/>
<file name="2ndrequireddll.dll"/>
</assembly>
これで、アセンブリマニフェストが作成されました。半分完了しました。
次の半分は、実際に dll にアセンブリを使用させることです。そのためには、DLL ファイルにマニフェスト リソースを追加する必要があります。そのマニフェストには、最終的に次のコンテンツを含める必要があります:-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="MyAssembly" version="1.0.0.1" processorArchitecture="*"/>
</dependentAssembly>
</dependency>
</assembly>
どうやらアプリケーション マニフェスト (dll に埋め込まれている場合は紛らわしい名前です) も<file>
ノードを使用できるようになっているため、アセンブリの作成をスキップしてそのまま使用することも可能です。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="firstrequireddll.dll"/>
<file name="2ndrequireddll.dll"/>
</assembly>
dll のマニフェストとして。私はまだその繰り返しをいじっていないので、それが通常のdll検索パスをどのように変更するかはわかりません(もしあったとしても)。
開発環境を知らなければ、マニフェストを dll に追加する方法をアドバイスする方法を知るのは困難です。.rc ファイルを編集して手動でマニフェストを入力する場合、DLL で使用するリソース ID は 1 ではなく 2 であることに注意してください。これは通常、exe の例で使用されます。
DevStudio 2005 以降を使用している場合は、便利な #pragma ディレクティブがあり、すべてが魔法のように正しい ID を持ち、正しい場所に配置されます。
プロジェクト設定がデフォルトの場合、VS2005 以降は自動的に生成され、必要に応じてマニフェストが埋め込まれます。この #pragma は、生成されたマニフェストに追加のアセンブリ依存関係を追加します:-
#if _MSC_VER >= 1400 // VS2005 added this directive
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Company.Product.Subsystem' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"language='*'\"")
#endif