間接DLLがデバッグDLLから適切にインポートされない
-
02-07-2019 - |
質問
VC2005を使用して、3つのプロジェクトをビルドします:
- libA(typelibを含み、libA.dllになります):IDLには
library libA { ...
という行があります
- libB(libAをインポートするtypelibを含み、libB.dllになります):IDLには次の行があります
importlib( "libA " );
- libC(libBをインポート):ソースファイルの1つに
#import <libB.dll>
が含まれています
__missing_type__
は、コンパイラーによって次の方法で処理されます(ドキュメントによる):
- %PATH%のディレクトリを検索
- %LIB%のディレクトリを検索
- <!> quot;追加のインクルードパス<!> quot;を検索します。 (/ Iコンパイラオプション)
libCをコンパイルすると、cl.exeが(Filemon.exeを使用して)実行可能パスでlibA.dllを明確に見つけることができることがわかります
VCエラーC4772:#別の依存関係を持つtypelibのインポート
ただし、libA名前空間はまだ見つかりません 、libA型へのすべての参照は<=>
に置き換えられます(編集)一方、問題はデバッグDLLを使用している場合にのみ表示されることがわかりました。
この問題を以前に見た人はいますか?そしてそれを解決しましたか?
解決 4
ついに見つかりました!
Visual Studioプロジェクトでは、LibAのA.idlファイルの MkTypeLib Compatible 設定がオンになっています。これは、Aプロジェクトから継承された動作を無効にしました。さらに悪いことに、デバッグ構成でのみオンになりました。
結果は、すべての
typedef [public] tagE enum { cE1, cE2 } eE;
これにより、tagE
が結果のtypelibで定義されなくなりました。 LibBがimport( "A.dll" )
を実行したとき、__missing_type__
へのすべての参照は<=> ...
他のヒント
プロジェクトの依存関係を明示的に設定していますか?言い換えれば、プロジェクトCがプロジェクトBに依存し、プロジェクトBがプロジェクトAに依存するように、IDEでソリューションを設定しましたか?
libCからlibAで定義された型を使用していますか?もしそうなら、libCからlibAを直接インポートして、libAのタイプを知る必要があると思います。 COMは、それ自体が別のタイプライブラリによって参照されているタイプライブラリを自動的に参照しません。
あなたに答えはありませんが、この経験は何度かありました。私がしたことを共有したいと思います。
いくつかの無関係なプロジェクトで、同じシナリオがありました。あるケースでは依存関係を解決するために1週間近く試みましたが、スケジュールを守るために最終的には損失を削減する必要がありました。最終的に.tlhファイルで#includeを使用し(DLLでインポートを実行するとこれらが生成されます)、次に<!> quot; classic com <!> quot; .tlhファイル内の構造体へのポインターを取得するapi呼び出し。コードは、ラッパーファイルを使用できる場合ほどきれいに機能しませんが、機能します。
IUnknown *lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&lpUnk);
if (FAILED(hr)) throw SomeException;
//
_Application *app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
lpUnk->Release();
if (FAILED(hr)) throw SomeException;
// Do stuff with the app object
app->Release(); // Then release
やや<!> quot; de-uglify <!> quot;これは、CComPtrラッパーテンプレートを使用して、範囲外になったときにデストラクタから確実にリリースを実行します。
CComPtr<IUnknown> lpUnk;
hr = CoCreateInstance(clsID, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)lpUnk);
if (FAILED(hr)) throw SomeException;
//
CComPtr<_Application> app; //Address _Application
hr = lpUnk->QueryInterface(__uuidof(_Application), (void **) &app);
if (FAILED(hr)) throw SomeException;
//
// Do stuff with the app object
_Applicationポインターは、.tlhファイルの構造の1つの使用例であることに注意してください。