zoukankan      html  css  js  c++  java
  • 【windows8开发】C++开发WinRT组件和JS调用

          通过Windows Runtime(以下简称WinRT),可以用C++或C#或VB很方便的开发组件(dll),并且这些组件在用Javascript开发的Metro app中可以几乎无缝的被(javascript)调用。由于win8开发平台下,Javascript并不能访问原生的C++代码(虽然可以访问WinRT API),而实际开发中,经常会有一些既存的组件,或者需要用一些第三方库,这时就可以考虑把这些组件或希望利用的库包装成WinRT组件供UI层(JS)调用,
    让我们来看一个具体的例子吧。以下代码在Beta版VS2011中可以编译运行。 

    创建WinRT Dll工程,工程名为TestLib,代码如下
    .h文件:
    #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以下所有的质数,并返回结果

    cpp文件:
    #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中取得计算结果。另外在计算中途,可以从最后一个回调函数中得到后台计算的进度。

    总的来说,组件的封装和调用还是挺简单的,大家的意见又如何呢?
  • 相关阅读:
    [LeetCode] Duplicate Emails 重复的邮箱
    [LeetCode] Flatten Nested List Iterator 压平嵌套链表迭代器
    [CareerCup] 15.4 Types of Join 各种交
    [LeetCode] Employees Earning More Than Their Managers 员工挣得比经理多
    [LeetCode] Consecutive Numbers 连续的数字
    [LeetCode] Rank Scores 分数排行
    [CareerCup] 15.3 Renting Apartment III 租房之三
    [CareerCup] 15.2 Renting Apartment II 租房之二
    [LeetCode] 340. Longest Substring with At Most K Distinct Characters 最多有K个不同字符的最长子串
    [CareerCup] 15.1 Renting Apartment 租房
  • 原文地址:https://www.cnblogs.com/secbook/p/2655114.html
Copyright © 2011-2022 走看看