将 C++ 应用程序向 Windows 8/Windows Phone 8 迁移时,首先要考虑的是用户界面。几乎没有哪个应用的界面能适合以触摸为中心的 Windows 8 界面。UI 层有四个选项:
- DirectX 与 C++
- XAML 与 C++
- XAML 与.NET
- Windows RT 之上的 HTML5
因为 UI 需要重写而非移植,本文不会涉及这些技术。
很多 Win32 和 COM API 直接无法使用了。其他 API 也会受到一些限制,因此即便有的 API 仍然存在,其行为与过去可能也不太一样。之所以限制这些 API,除安全性之外,还因为它们对电池续航时间有负面影响,或者因为无法匹配新的应用程序生命周期。此外,所有的 GDI 子系统都被禁用。
与传统的 COM 不同,开发者无法定义自己的跨应用通信协议。而且因为套接字限制,简单地监听本地端口也不再有效。这一决策背后的基本理论是“WinRT 应用程序应该是完全隔离的”。这意味着开发者无法一次性安装一个应用程序集。
开发者可以通过宏 WINAPI_FAMILY_PARTITION 来获取编译错误信息,从而确定哪些 API 不再支持。这个过程可能会让人有点沮丧,比如下面这种情形:如果禁用的 API 调用使用了缺失的结构体,那么缺失结构体的报错信息会分散开发者的注意力。
微软的 Tarek Madkour 建议使用 Windows 应用程序验证工具包(Windows Application Certification Kit)而非宏来迁移现有的库。我们可以这样做,创建一个新的基于 XAML 的应用程序,并引用所有要移植的库。然后运行一次该应用程序以便它部署在计算机上。下一步对应用程序运行验证工具包,这样就可以生成需要替换或移除的 API 列表。
这方面还有一个资源:Windows 应用商店应用中 Windows API 的替换选择( Alternatives to Windows APIs in Windows Store apps )。
线程
WinRT 不支持经典的 CreateThread API 调用。这种功能一般使用 WinRT ThreadPool 类来实现。WinRT ThreadPool 的一个主要缺点是标准的 Windows 应用程序没有相应支持。下面几个可选项没有类似限制。
对于寻求高级抽象的人而言,并行模式库任务( Parallel Patterns Library Tasks )提供了另一种选择。
更低层次地访问可以使用 C++ 的 std::thread 和 std::future 。从更广的角度看,微软想要在其所有的设备和操作系统上支持标准 C++。
最底层的选择是 VC++ 运行时的 beginthread 函数。根据 Tarek 的说法,它提供了“最强的能力,不过控制不好可能砸到自己的脚”。不过这里请注意:Tarek 的说法与微软的描述正相反,上面链接说不支持该 API。
异步
许多要基于 Windows 8 开发应用程序的 C#、VB 和 C++ 开发者应该熟悉新的异步模式与 lambda 表达式语法。
库的暴露
虽然大部分库可以直接用 C++ 编写,但是任何需要暴露给其他语言的部分都应该选择以 C++/CX 编写的组件的形式。从性能上看,这种方式一般比正常的 C++ 链接方式要差,因此 C++ 程序不应使用这样的库。
WinRT 应用程序既不支持 C 也不支 C++/CLI。
查看英文原文: Porting Existing C++ Code to Windows 8/Windows Phone 8
感谢贾国清对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论