【Windows8开发】关于WinRT组件,WinRT dll,Win32 dll,WinRT exe组件的一些尝试

随着Win8的推出,提出了很多新的概念,比如WinRT Component,WinRT dll,WinRT exe component等。基于这些新的概念,进行了很多尝试,本文会把结果分享给大家,希望对大家能有所触发。

1. WinRT Component, WinRT dll,Win32 dll区别与联系
前面系列文章中提到了n多的WinRT Component(WinRT组件)。那到底什么是WinRT组件呢?傻瓜式的解释就是:被编译为面向WinRT的组件就是WinRT组件,虽然这等于一句废话,但却是一句大实话。其实之所以开发出WinRT组件的最大目的就是为了使组件能更好的支持被多种开发语言使用(js,C++, C#/VB)。而为了让开发者可以更方便的开发WinRT组件,微软又扩展了C++,也就是所谓的C++ /CX,所以基于C++ /CX风格的WinRT组件在接口风格,export形式上跟传统dll会有一定区别。

那WinRT dll呢?在VS2012中新建工程时可以看到,有个模板工程 Dll(windows store apps),就是用来开发WinRT dll的。那WinRT dll到底是个什么东东?跟WinRT组件有什么区别呢?其实很简单,可以把WinRT dll就看做是传统的Win32 dll,它们都是按照传统dll的封装形式,把接口或者类export出来,唯一的区别就是WinRT dll可以支持WinRT及其API。VS工程属性中可以进行设置,Win32 dll工程中会是No,而WinRT dll中则是Yes:


顺便提一下,当你创建WinRT dll工程时,默认情况下是不支持WinRT API以及C++ /CX的,如果需要支持则需要进行如下改动:

注意当这里追加/ZW属性后,则一定要把/GM项去掉:


2. 在Windows Store app中如何复用传统Win32 dll
Win8推出在即,各种程序都会考虑在Windows store app上的移植,传统Windows项目中的dll如何在新平台中复用呢?可以复用吗?说简单也很简单。新建一个WinRT dll的工程,把原来dll的代码和配置直接移过来,编译时应该会发现一堆错误,基本应该都属于原来代码中用到了很多WinRT中不再支持的API,关于API的整合可以参考下文:

首先就是把所有不支持的API替换成WinRT中支持的形式,比如Thread,Socket等常规API,然后编译可以通过后,如果你的Windows Store app本身就是想用C++实现,那你可以在app中直接象往常加载dll一样的调用方式(导入lib或者LoadLibrary),就可以使用WinRT dll了。如果你的app本身要用C++以外的语言,C#或者js,那最好还是再封装一个WinRT组件,把WinRT dll的接口包进来,方便被App调用。(有些文档中说可以在C#等app中直接add reference来关联WinRT dll,但我试下来都失败了)

3. 使用WinRT exe component
什么是WinRT exe组件?貌似相关的文档很少,但在微软提供的C++ sample程序中有个名字是Creating a Windows Runtime EXE component with C++的实例,简单研究了下,发现其实跟“Com进程外组件”的概念非常类似,就是一个为Windows store app提供服务的exe组件,不了解的可以找Com相关的资料来看看。当你运行的app中调用了这个exe组件时,此exe会自动运行被把执行结果返回给此程序。从这一点来看,跟Win8 Metro模式下宣称的单进程app似乎有所不符,也就是说其实在一个Windows store app中,是可以跑多个进程的,而且发现,当前台app被suspended后,提供服务的的exe组件仍旧会照常运行,这似乎为很多程序提供了一种额外可以变通的解决方案。但由于资料过少,还没有深入研究过,如果有谁有更多信息的,期待分享。

4. Windows桌面程序中如何调用WinRT API
记得在前面的文章中也多次提到过,部分WinRT API被定义为在desktop app和Windows store app中都可以使用,如下所示,StreamSocket class:

那在桌面程序中又是如何去使用这些WinRT API呢?直接通过模板工程直接调用肯定是不行的,至少目前版本的VS2012没有如此智能的Wizard,我简单的进行了一些尝试,大家一起看看结果如何。

首先让我们看看在C# console桌面app中是否可以调用WinRT提供的API。新建C# console工程后,为了调用WinRT API,无疑就要导入Windows.winmd这个关于WinRT API的metadata文件以及相关dll。具体操作请参照如下步骤:
1. 修改工程属性(否则会导入失败),右击刚才创建的工程,选择 unload project,然后编辑工程的.csproj文件,如下所示,添加<TargetPlatformVersion>:

2. 重新Reload Project

3. 导入Windows.winmd。为工程Add Reference,如下所示:

4. 引入System.Runtime.dll。此dll一般在如下路径,通过Add Reference把它导入到工程中:
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades

5. 设置OK了,写段代码尝试下吧。
using Windows.Networking.Sockets;

namespace Win32CSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            DatagramSocket sock = new DatagramSocket();
        }
    }
}

编译运行,一切正常。

那C++中又如何呢?同理先新建一个Win32 Console的工程,修改下工程属性,如上曾经提到过的,设置/ZW以支持WinRT,同时去掉/GM避免编译冲突。然后在工程属性 [C++] - [General] - [Additional #using Directories]中追加如下WinRT metadata文件的路径:

 Ok,写段代码尝试一下:
#using <Windows.winmd>

int main(void)
{
       Windows::Networking::Sockets::DatagramSocket^ sock = ref new Windows::Networking::Sockets::DatagramSocket();
       return 0;
}

编译通过了,但运行失败。应该是WinRT API相关dll不能被正常加载,还进行了一些其他的尝试,不过还是没有成功,如果谁有这方面经验的,期待大家的分享。

以上内容只是一些粗浅的尝试,可能结论并不周全,或者随着WinRT版本的更新会产生一些变化,如果大家发现任何问题,欢迎留言。


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值