Использование в TypeScript классов .Net

377
14 января 2017, 12:52

Есть идея иметь доступ из TypeScript к методам и свойствам классов .Net.

У меня есть опыт вызова методов .Net объектов из натива https://habrahabr.ru/users/serginio1/topics/

И в частности Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux

Есть идея вызвать через Native Client Messaging System

Там мы имеем взаимодействие JavaScript и натива через сообщения

В JavaScript мы можем подписаться на события

function handleMessage(message) {
  // In the example, we simply log the data that's received in the message.
  var logEl = document.getElementById('log');
  logEl.textContent += message.data;
}

И отправлять сообщения

var dictionary = {
  key:guid,
  MethodName: name,
  param_array: args
}
nacl_module.postMessage(dictionary);

На стороне натива

Можно принмать сообщения

virtual void HandleMessage(const pp::Var& var) {
  if (var.is_dictionary()) {
    pp::VarDictionary dictionary(var);
    // Use the dictionary
    pp::VarArray keys = dictionary.GetKeys();
    // ...
  } else {
    // ...
  }
}

Так и отправлять

pp::VarDictionary dictionary;
dictionary.Set(pp::Var("command"), pp::Var(next_command));
dictionary.Set(pp::Var("param_int"), pp::Var(123));
pp::VarArray an_array;
an_array.Set(0, pp::Var("string0"));
an_array.Set(1, pp::Var("string1"))
dictionary.Set(pp::Var("param_array"), an_array);
PostMessage(dictionary);

Все это можно сделать через Proxy

class NetWrapper{
    public currentCount: any;
    public static dictionary = {};
    public proxy: any;
    public static wm = new WeakMap(); // Слабые ссылки на объекты
    public static refArray = new Array<int>(); // ссылки на .Net объекты   
    constructor(private netRef:int) { this.SetProxy(); }

     private GetPromise(name: PropertyKey,args)
    {
        let key = Guid.newGuid();
        let promise = new Promise((resolve, reject) => {
            let item = new Item(resolve, args, name);
            this.dictionary[key] = item;
           var dictionary = {
           netRef:netRef,
           key:key,
           MethodName: name,
           param_array: args
         }
          nacl_module.postMessage(dictionary);
        });

        return promise;
    }

    private SetProxy(): void {
        let self=this;
        this.proxy = new Proxy({}, {
            get: function(rcvr: any, name: PropertyKey)
            {
               // Проблемы с определением, что свойство возвращает ссылку на метод
               // поэтому будем вызвать все как методы
               // if (этоСвойство)
               //     return self.GetPromise(name, []);
               return (...args) => {
                   return self.GetPromise(name,args)
                };

            }

        });
    }


// Пример вызова метода .Net
function handleMessage(message) {
  // In the example, we simply log the data that's received in the message.
  let data=message.data;
  let result=data.result;
  let item = <Item>this.dictionary[data.key];
  delete this.dictionary[key];
  if (data.resultIsObject)
   {
    let ref=<int>result;
    result=new NetWrapper(ref);
    refArray.push(ref);
    wm.set(result,ref);
  }
  item.resolve(result);
}

Так как в в JavaScript нет финализаторов, то можно использовать WeakMap

То есть можно было бы выгрузить значения из wm и сравнить их с текущим массивом ссылок refArray. Если в WeakMap ссылок нет значит можно освободить ссылки и на стороне .Net

Но вроде как

Из-за того, что ссылки являются слабыми, ключи WeakMap не перечисляемы (то есть нет метода, который возвращает список ключей). Иначе список бы зависел от состояния сбора мусора, представляя индетерминизм. Если Вы хотите иметь список ключей, Вам следует поддерживать его самостоятельно.

Использование такое

  let HttpClient=await NetWrap.GetType("System.Net.Http.HttpClient","System.Net.Http.dll");
     let HttpClientHandler = await NetWrap.GetType("System.Net.Http.HttpClientHandler","System.Net.Http.dll");
    let client=await NetWrap.new(HttpClient);
    let responst= await (await client.GetStringAsync("https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx")).Result();
 //Result вызываем как функцию

Можно для асинхронных методов result внутри Net сделать асинхронным

Буду рад любым советам. И может это никому и не нужно и не стоит вообще писать в стол?

Правда нашел ссылку на возможность финализатора https://www.npmjs.com/package/finalize

var finalize = require('finalize');
 
var obj = { x: 1337 };
finalize(obj, function () {
  console.log(this.x); // this will print '1337' 
});
global.gc();
// nothing will happen, var obj above holds obj alive 
obj = null;
global.gc();
// the previous line should trigger the callback above 
READ ALSO
Web framework для языка c/c++

Web framework для языка c/c++

Здравствуйте! Вопрос такойСобираюсь писать приложение где требуется что бы все работало очень быстро

327
Structure Definitions [требует правки]

Structure Definitions [требует правки]

Прочел в книгах не очень-то понял про Structure Definitions C++Вкратце объясните плес

268
Как вызвать родительский метод из тела перегруженного в С++?

Как вызвать родительский метод из тела перегруженного в С++?

Есть классУ него есть другой класс-наследник

262