Каковы языковые прогнозы WinRT? - PullRequest
17 голосов
/ 15 сентября 2011

Что такое языковые проекции WinRT и для чего они используются?

Ответы [ 4 ]

12 голосов
/ 16 сентября 2011

Прогнозы среды выполнения Windows - это способ представления API среды выполнения Windows на каждом языке. Это может быть во время компиляции (как в C ++) или во время выполнения (как в JavaScript) или в комбинации (как в C #). Каждый язык решает, как лучше всего представить API WinRT. В большинстве случаев это прямое воздействие, но в других случаях возможны обертки или перенаправления. Делегаты и мероприятия являются хорошим примером. В C # они отображаются как делегаты / события C #, а не как типы, специфичные для WinRT. Строки также преобразуются в строковый тип родного языка, а не в базовый тип hstring.

10 голосов
/ 15 сентября 2011

«Проекции» в WinRT - это еще одно слово для «Привязки».

Языковые проекции WinRT - это привязки WinRT для каждого поддерживаемого языка.

Для получения дополнительной информации, проверьте:

WinRT Демистифицировано - Мигель де Иказа

4 голосов
/ 16 сентября 2011

Самый простой способ прояснить это, что языковая проекция в WinRT является «внешним интерфейсом», тогда как Windows Runtime является внутренним. Пишите на одном из трех языков (JS, C #, VB), он ведет себя одинаково на внутреннем сервере.

Если вы пишете свой собственный сторонний компонент WinRT на C ++ или C #, вы можете использовать его из JS, C # и VB, не выполняя никакой дополнительной работы.

1 голос
/ 22 февраля 2019

Языковая проекция - это способ познакомить вас с API среды выполнения Windows без использования языков.

Например, лежащий в основе способ создания Windows.Globalization.Calendar объекта - вызов:

IInspectable instance;
HRESULT hr = RoActivateInstance(StringToHSTRING("Windows.Globalization.Calendar"), out instance);
if (Failed(hr))
   throw new ComException(hr);

ICalendar calendar;
hr = instance.QueryInterface(IID_ICalendar, out calendar);
if (Failed(hr))
   throw new ComException(hr);

Это то, что большинство языков называют "конструктором" . Но большинство языков уже имеют синтаксис «создать объект» .

Если вы находитесь в C #, у вас есть:

Calendar calendar = new Calendar();

Если вы в Паскале, у вас есть:

calendar: TCalendar;

calendar := TCalendar.Create;

Итак, давайте создадим C # -подобную оболочку (или проекция ) вокруг этого:

class Calendar : Object
{
   private ICalendar _calendar;

   //constructor
   void Calendar() : base()
   { 
      IInspectable instance;
      HRESULT hr = RoActivateInstance(StringToHSTRING("Windows.Globalization.Calendar"), out instance);
      if (Failed(hr))
         throw new ComException(hr);
      ICalendar calendar;
      hr = instance.QueryInterface(IID_ICalendar, out calendar);
      if (Failed(hr))
         throw new ComException(hr);

      this._calendar = calendar;
   }
}

И теперь вы можете использовать дружественную C # -подобную проекцию:

Calendar cal = new Calendar();

Паскаль версия конструкторов

Допустим, вы используете Delphi: у вас уже есть идиома для создания объектов. Позволяет преобразовать основную сантехнику в дружественную проекцию Паскаля:

TCalendar = class
private
   FCalendar: ICalendar;
public
   constructor Create;
end;

constructor TCalendar.Create;
var
   instance: IInspectable;
   calendar: ICalendar;
   hr: HRESULT;
begin
   inherited Create;

   hr := RoActivateInstance(StringToHSTRING('Windows.Globalization.Calendar'), {out} instance);
   OleCheck(hr);

   hr = instance.QueryInterface(IID_ICalendar, {out} calendar);
   OleCheck(hr);

   FCalendar := calendar;
end;

И теперь у нас есть проекция Дельфи :

calendar: TCalendar;

calendar := TCalendar.Create;

Свойства (используйте их, если у вас есть)

В базовом интерфейсе ICalendar вы должны получить и установить свойства, используя методы:

  • get_Year

Если вы слепо перевели это на C #, вы можете получить:

C # Методы свойства:

class Calendar : Object
{
   private ICalendar _calendar;

   public int get_Year() { return _calendar.get_Year(); }
   void set_Year(int value) { _calendar.set_Year(value); }
}

Pascal Методы свойства:

TCalendar = class
public
   function get_Year: Integer;
   procedure set_Year(Value: Integer);
end;

Но если ваш язык поддерживает их, вы на самом деле должны выставить эти свойства как фактические "Свойства" . Таким образом, мы можем проецировать эти свойства, используя синтаксис свойства, свойственный нашему языку:

C #

class Calendar : Object
{
   private ICalendar _calendar;

   public int Year { 
         get { return _calendar.get_Year(); } 
         set { _calendar.set_Year(value); }
   }
}

Паскаль

TCalendar = class
public
   property Year: Integer read get_Year write set_Year;
end;

итераторы

Идея состоит в том, чтобы создать фасад, который будет выглядеть и ощущаться как ваш язык, но за кулисами он сопоставляется с базовыми вызовами. Это идет довольно глубоко.

В WinRT все перечисляемое реализует

  • IIterable<T>

Но в C # все перечисляемое должно начинаться с:

  • IEnumerable

Таким образом, библиотека .NET имеет внутренний класс, который адаптирует IIterable<T> и представляет его как IEnumerable.

Таким образом, вместо метода, возвращающего IIterable<T>:

class Calendar : Object
{
   public IIterable<Datetime> Holidays()
   {
      return _calendar.Holidays();
   }
}

Возвращает IEnumerable<T>:

class Calendar : Object
{
   public IEnumerable<DateTime> Holidays()
   {
       IIterable<DateTime> iter = _calendar.Holidays();

       //Create helper class to convert IIterable to IEnumerable
       IEnumerable<DateTime> enum = new IteratorToEnumeratorAdapter(iter);

       return enum;
   }
}

Таким образом, вы можете использовать собственный язык:

  • foreach date in Holidays
  • for date in Holdays do

Что за дата?

В WinRT даты представлены в виде Windows.Foundation.DateTime:

class Calendar : Object
{
   //Windows.Foundation.DateTime
   Datetime Date { get { return _calendar.get_Date(); } set { _calendar.set_Date(value); }
}

Но на других языках у нас уже есть свои datetime классы:

  • C # : System.DateTimeOffset
  • Javascript : Date
  • C ++ : FILETIME
  • Delphi : TDateTime

Таким образом, проекция выполняет преобразование WinRT DateTime (Int64, который является числом интервалов 100 нс с 1 января 1601 г.) в C # DateTimeOffset:

class Calendar : Object
{
   //System.DateTimeOffset
   DateTimeOffset Date { 
       get { 
          Int64 ticks _calendar.get_Date().UniversalTime(); 
          DateTimeOffset dt = DateTimeOffset.FromFileTime(ticks);
          return dt;
       } 
       set { 
          Int64 ticks = value.ToFileTime();

          DateTime dt = new Windows.Foundation.DateTime();
          dt.UniversalTime = ticks;
          _calendar.set_Date(dt);
       }
}

и что-то похожее на Delphi TDateTime :

type
   TCalendar = class(TObject)
   private
      FCalendar: ICalendar;
      function getDate: TDateTime;
      procedure setDate(Value: TDateTime);
   public
      property Date: TDateTime read getDate write setDate;
   end;

   function TCalendar.GetDate: TDateTime;
   var
      ticks: Int64;
   const
      OA_ZERO_TICKS = Int64(94353120000000000);
      TICKS_PER_DAY = Int64(864000000000);
   begin
      ticks := FCalendar.get_Date().UniversalTime;
      Result := (ticks - OA_ZERO_TICKS) / TICKS_PER_DAY;
   end;

   procedure TCalendar.SetDate(Value: TDateTime);
   var
      ticks: Int64;
   const
      OA_ZERO_TICKS = Int64(94353120000000000);
      TICKS_PER_DAY = Int64(864000000000);
   begin
      ticks := (Value * TICKS_PER_DAY) + OA_ZERO_TICKS;
      FCalendar.set_Date(Round(ticks));
   end;    

ТЛ; др

Проекция - это набор оберток вокруг WinRT, чтобы он выглядел максимально приближенным к вашему родному языку.

В C # никто на самом деле не пишет прогнозируемые версии; компилятор и среда выполнения выполняют всю работу за кулисами, поскольку умеют читать метаданные.

Для других языков переведенные файлы кода создаются вручную или автоматически с помощью инструмента импорта.

...