3

ATL コレクション、ATL CString、および CComPtr を使用した COM インターフェイスを多用する C++ で開発された Windows ライブラリがあります。Winrt で許可されていないすべての API 呼び出しをライブラリから削除しましたが、正常にビルドされたので、ライブラリを C++/CX ref-class でラップし、Windows ストア アプリから使用しようとしています。アプリケーションは正常に動作しますが、Win-Store アプリの認証は次のエラーで失敗します:

エラーが見つかりました: サポートされている API テストで次のエラーが検出されました: kernel32.dll の API GetModuleHandleW は、このアプリケーション タイプではサポートされていません。MyLibrary.dll は、この API を呼び出します。kernel32.dll の API InitializeCriticalSectionAndSpinCount は、このアプリケーション タイプではサポートされていません。MyLibrary.dll は、この API を呼び出します。

私のライブラリの VS プロジェクトは、次の設定で Windows ストア用に構成されています。

ここに画像の説明を入力

これらの設定により、SDK で必要なマクロ (たとえば、WINAPI_FAMILY_APP としての WINAPI_FAMILY) が期待どおりにアクティブ化/非アクティブ化されます。

ライブラリで GetModuleHandleW または InitializeCriticalSectionAndSpinCountを直接呼び出していないことは 100% 確信しているため、この問題は、Windows 8 SDK で適切にフィルター処理されていない ATL クラスのメソッドに起因するに違いないと考えました。

ATL ヘッダー ファイルに飛び込むことは、すべてが適切にフィルター処理されているように見えるため、あまり役に立ちませんでした。たとえば、ATL::CComCriticalSection::Init のこのフラグメントを参照してください。

#if !defined(_ATL_USE_WINAPI_FAMILY_DESKTOP_APP) || defined(_ATL_STATIC_LIB_IMPL)
        if (!_AtlInitializeCriticalSectionEx(&m_sec, 0, 0))
#else
        if (!InitializeCriticalSectionAndSpinCount(&m_sec, 0))
#endif

私の理論を証明するために、16 進エディターを使用して Kernel32.lib ファイルから GetModuleHandleW を編集したところ、次のリンク エラーが表示されました。

atls.lib(atlwinverapi.obj): エラー LNK2001: 未解決の外部シンボル __imp__GetModuleHandleW@4

ですから、私の理論は間違っていないようです。デバッグ ビルドは認定に合格しないため、リリース ビルドを使用してこれらすべてを行っていることに注意してください。

今質問:

ヘッダー ファイルを見る以外に、ATL 内のどのクラスがライブラリを妨害しているのかを正確に知る方法はありますか?

MSDN フォーラムでの同じ質問

この問題を再現する小さなサンプル コードを使用して、Microsoft Connect に関するバグ レポートを追加しました。

4

1 に答える 1

1

これが私が推測するものです。ファイル atlwinverapi.h を見てください。マクロ _ATL_NTDDI_MIN は、条件付きで x86/x64 用と ARM 用の別の方法で定義されています。

これは、XP サポートを追加した最近の VSUpdate で変更された可能性があると思います。ファイル atlwinverapi.cpp (これは atls.lib にあると思います) のメソッド _AtlInitializeCriticalSectionEx で、_ATL_NTDDI_MIN < NTDDI_VISTA の場合、InitializeCriticalSectionAndSpinCount を呼び出していることがわかります。

x86 または x64 を構築していると想定しているため、この問題が発生しています。ARM 用にビルドする場合、この問題は発生しません。

もちろん、ARM で WACK を実行することはできませんが、バイナリで dumpbin /imports を実行して、準拠していない API がまだ使用されているかどうかを確認できます。

于 2012-12-19T03:36:30.550 に答える