UWP中重用C/C++代码时踩过的一些坑

发表于:2016-6-29 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:MS-UAP    来源:51Testing软件测试网采编

  标题中提到的UWP,主要是指用C#来写UWP的主工程,开发过程中可能需要调用C/C++实现的库。
  为什么需要调用C/C++的库呢,举个例子,开源库OpenSSL实现了许多加密算法,稳定快速,我们想在应用中调用;再比如,应用已经在iOS/Android平台上线并稳定运行了,我想把它们的库拿来给UWP版本用。
  经过一些项目的实践,我总结了下图所示的几种集成方式:
  图中红叉不代表此路不通,只是我们今天不讨论P/Invoke方式。我们今天主要通过WinRT来打通C#和C/C++之间的调用,因此,我们的选择应是前两种路线。前两种路线的区别在于,一个直接用原有代码创建了一个WinRT,另一个是使用WinRT将原DLL的接口进行包装,方便C#调用。
  坑1:代码移植
  下载需要的开源库,按照默认编译选项,很轻松得到了dll文件,然后新建一个WinRT,将dll包装一下,提供给C#使用,简单几步就将开源库集成到UWP中了,但是,在发布到商店时,可耻的失败了。
  由于我们的UWP应用最终是要发布到商店中的,所以必须要能通过商店的认证才可以。开发环境本地就可以检测x86架构的安装包是否符合商店要求,使用的工具是Windows App Cert Kit,后面我们简称它为WACK,该工具随Win10 SDK一起安装。你可以通过小娜快速启动这个工具,直接在小娜中输入Windows App Cert Kit或Cert就可以。
  现成的dll文件很可能是无法通过商店认证的,快速检测方法是可以将dll文件作为内容添加到工程中,打包并用WACK验证,大部分情况下会在支持的API那里验证不过。 https://msdn.microsoft.com/zh-cn/library/windows/apps/jj606124.aspx 这里列出了部分UWP中不能使用的API。所以,我们需要修改工程或代码,将这些不能使用的API都替换掉。这是一个非常痛苦的事情,我要一行一行代码来找哪些API不能用吗?我要自己修改编译选项,加各种宏吗?太可怕了!
  一种简单的做法是这样的,新建一个Windows通用工程,如下图所示,这个工程默认是配置好编译选项和宏的,编出来的库可以符合商店的认证规则。然后将原代码添加到工程中,编译,输出窗口中会打印出哪些函数是不能用的,我们可以快速定位并进行相应替换或代码更改。
  坑2:引用
  如果是直接引用的工程文件,此处可能不会出坑,因为VS会很贴心地将所有必需的文件复制到该去的位置;如果是引用的编译出来的winmd文件,那么就要注意一些事情了。
  我们来看一下编译输出的文件,如果是第一种路线,输出一个winmd和一个dll,将它们放在一起,只需要引用winmd文件就可以了,VS知道编译的时候带上dll文件;如果是第二种路线,输出一个winmd和两个dll,多出来的dll是动态库的工程生成的,此时除了引用winmd文件外,还需要将额外的dll文件直接添加到主工程中,同时将文件属性中的"生成操作"设置为"内容"。
  完成上面的引用后,我们还需要在主工程中添加 Visual C++ 2015 Runtime for Universal Windows Platform Apps 和 Microsoft Universal CRT Debug Runtime ,具体添加方式是在工程上右键- > 添加 -> 引用 -> Universal Windows -> 扩展。如果不添加,有可能在运行时会收到莫名其妙的找不到文件的崩溃。
  最后,提一下如何设置X86/ARM分别引用不同的文件,在添加完对winmd文件的引用后,用记事本打开工程文件,找到刚才引用的winmd文件这里,在路径中使用$(PlatformTarget)来代替X86/X64/ARM,使用$(Configuration)来代替Debug/Release,这样,VS在编译的时候就可以为不同的目标使用不同的库文件了。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号