|
楼主 |
发表于 2012-8-3 13:04:38
|
显示全部楼层
通过上面的两章,我们对win8已经有个基本的了解,下面我们就开始谈谈具体的dll的封装和JS调用。
我们在Windows Runtime下(以下简称WinRT),可以用C++或C#或VB很方便的开发组件(dll),并且这些组件在用Javascript开发的Metro app中可以几乎无缝的被(javascript)调用。由于win8开发平台下,Javascript并不能访问原生的C++代码(虽然可以访问WinRT API),而实际开发中,经常会有一些既存的组件,或者需要用一些第三方库,这时就可以考虑把这些组件或希望利用的库包装成WinRT组件供UI层(JS)调用,
让我们来看一个具体的例子吧。以下代码在Beta版VS2011中可以编译运行。- #pragma once
- #include <amp.h>
- #include <collection.h>
- namespace TestLib
- {
- public ref class WinRTComponent sealed
- {
- public:
- WinRTComponent();
- void SyncFunc(int number);
- Windows::Foundation::IAsyncOperationWithProgress<Windows::Foundation::Collections::IVector<int>^, double>^ AsyncFunc(int number);
- private:
- bool is_prime(int n);
- };
- }
复制代码 组件中类名为WinRTComponent,作为组件类,考虑到外部调用,声明为public,同时也声明为引用类型ref,它包含两个public方法,
SyncFunc方法为以同步调用方式计算出number值以下所有的质数,并返回结果
AsyncFunc方法为以异步调用方式计算出number以下所有的质数,并返回结果- #include "pch.h"
- #include "WinRTComponent.h"
- using namespace TestLib;
- using namespace Platform;
- using namespace Concurrency;
- using namespace Platform::Collections;
- using namespace Windows::Foundation::Collections;
- using namespace Windows::Foundation;
- WinRTComponent::WinRTComponent()
- {
- }
- bool WinRTComponent::is_prime(int n)
- {
- if (n < 2)
- return false;
- for (int i = 2; i < n; ++i)
- {
- if ((n % i) == 0)
- return false;
- }
- return true;
- }
- void WinRTComponent::SyncFunc(int number)
- {
- auto primes = ref new Vector<int>();
- for (int i = 0; i < number; i++) {
- if (is_prime(i)) {
- primes->Append(i);
- }
- }
- }
- IAsyncOperationWithProgress<IVector<int>^, double>^ WinRTComponent::AsyncFunc(int number)
- {
- return create_async([this, number](progress_reporter<double> reporter)-> IVector<int>^ {
- auto primes = ref new Vector<int>();
- double progress = 0.0;
- double curProgress = 0.0;
- for (int i = 0; i < number; i++) {
- if (this->is_prime(i)) {
- primes->Append(i);
- }
- curProgress = 100.0 * i / number;
- if (curProgress > progress) {
- progress = curProgress;
- reporter.report(curProgress);
- }
- }
- reporter.report(100.0);
- return primes;
- });
- }
复制代码 AsyncFunc方法中,create_async函数是通过异步的方式创建一个异步调用,使计算在后台进行,而程序不会阻塞在质数统计的计算中。其中有个匿名函数Lambda表达式的使用,这是C++ 0x/11中支持的新特性。
另外,以上代码中ref,^等与传统C++不同的特性在本文中就不作说明了,在这个系列的其他文章中会有说明。
最后是javascript对以上组件dll的调用,代码如下:- // 新建WinRTComponent对象
- var testlib = new TestLib.WinRTComponent();
- // 异步方法调用
- testlib.asyncFunc(1000).then(
- function (v) {
- // get result from v
- },
- function (error) {
- },
- function (p) {
- // get progress
- }
- );
- // 同步方法调用
- var vec = testlib.syncFunc(1000);
复制代码 异步方法调用后会立刻返回,在后台计算结束后会调用第一个回调函数,可以从参数v中取得计算结果。另外在计算中途,可以从最后一个回调函数中得到后台计算的进度。
总的来说,组件的封装和调用还是挺简单的,并不难掌握!
|
|