【问题标题】:Certification fails for Windows Store App with ATL-based library使用基于 ATL 的库的 Windows 应用商店应用程序认证失败
【发布时间】:2012-12-06 04:41:49
【问题描述】:

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

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

我的库的 VS 项目是为 Windows 应用商店配置的,具有以下设置:

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

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

深入研究 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 forums中的相同问题

我添加了一个bug report on microsoft connect,其中包含一个重现此问题的小示例代码。

【问题讨论】:

  • 当您在库中包含 ATL 标头时,您是否正确地将 WINAPI_FAMILY 宏设置为 WINAPI_FAMILY_APP?
  • @James MacNellis 该库的项目是为 Windows 应用商店配置的,我认为这就足够了,它会激活所需的宏,但我明天还是会尝试一下,谢谢你的提示.
  • @JamesMcNellis 我尝试了您的建议,但没有任何改变,如果您有任何其他可以帮助我的提示,请告诉我。谢谢
  • @yms 我认为您对 ATL 标头的使用是 WACK-clean,但是您从 atls.lib(静态库)使用的 API 之一最终使用了一些不兼容的 API,然后得到嵌入到您自己的二进制文件中。我想知道您的二进制文件究竟使用了 atls.lib 中的什么内容?我注意到 atls.lib 在 atlbase.h 中默认被拉入:#pragma comment(lib, "atls.lib")
  • @SometimesADeveloper 我想我找到了罪魁祸首,我认为是“CComCritSecLock”类,我必须仔细检查。

标签: c++ windows-8 visual-studio-2012 windows-runtime atl


【解决方案1】:

这是我的猜测。查看文件 atlwinverapi.h。宏 _ATL_NTDDI_MIN 有条件地定义为 x86/x64 的一种方式和 ARM 的另一种方式。

我认为这可能在最近添加 XP 支持的 VSUpdate 期间发生了变化。现在在文件atlwinverapi.cpp(我猜它进入atls.lib)中,在方法_AtlInitializeCriticalSectionEx 中,您会注意到如果_ATL_NTDDI_MIN

我假设您正在构建 x86 或 x64,这就是您看到此问题的原因。如果为 ARM 构建,则不会出现此问题。

当然你不能在 ARM 上运行 WACK,但你可以在你的二进制文件上运行 dumpbin /imports 看看它是否仍然使用那些不兼容的 API。

【讨论】:

  • 谢谢,这看起来很有希望。明天我将对此进行更深入的研究,并告诉你进展如何。
  • 如你所说,ARM build 没有使用禁用功能。
  • 感谢您的帮助。我添加了一个bug report on microsoft connect,其中包含一个重现此问题的小示例代码。
  • 既然你已经有效地识别了这个错误,我会选择这个作为答案,尽管我的问题还没有完全解决。让我们希望微软能尽快解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 2012-10-08
  • 2012-09-22
相关资源
最近更新 更多