3

我有一个用 C++ 开发的 Windows 库,它大量使用 ATL 集合、ATL CString 和 COM 接口与 CComPtr。我从库中删除了所有非 winrt 允许的 API 调用,并且构建良好,因此我将库包装在 C++/CX 引用类中,并尝试从 Windows 应用商店应用程序中使用它。应用程序运行正常,但 Win-Store 应用程序认证失败并出现以下错误:

发现错误:受支持的 API 测试检测到以下错误:此应用程序类型不支持 kernel32.dll 中的 API GetModuleHandleW。MyLibrary.dll 调用此 API。此应用程序类型不支持 kernel32.dll 中的 API InitializeCriticalSectionAndSpinCount。MyLibrary.dll 调用此 API。

我的库的 VS 项目为 Windows 应用商店配置了以下设置:

在此处输入图像描述

这些设置按预期激活/停用 SDK 中所需的宏(例如 WINAPI_FAMILY 为 WINAPI_FAMILY_APP)。

我 100% 确定我没有直接在我的库中调用 GetModuleHandleW 或 InitializeCriticalSectionAndSpinCount,所以我认为这个问题一定来自某些 ATL 类的方法,该方法在 Windows 8 SDK 中没有正确过滤。

深入 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

为了证明我的理论,我使用了一个十六进制编辑器并从我的 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 回答