Как вызвать функцию C # из фоновой задачи C ++ (приложение Windows Universal)?

Я переписываю свое приложение (с пользовательскими живыми плитками) в универсальное приложение. Ранее я использовал стороннюю библиотеку для рендеринга этих пользовательских живых плиток. Эта библиотека больше не поддерживается, поэтому мне нужно найти новый способ сделать это. Кажется, что XamlRenderingBackgroundTask пока единственный путь вперед, но это в C ++. А остальная часть моего приложения в C #.

Моя фоновая задача должна получить данные из общедоступного API (например, погода) и использовать эту информацию для рендеринга живой плитки. Я уже написал классы для извлечения данных (я также использую их в основном приложении), но они написаны на C #.

Теперь с компонентами среды выполнения Windows должна быть возможность «смешивать» разные языки (верно?). Но как мне этого добиться? (Образцы бетона отсутствуют).

Короче: Как я могу вызвать функции C # (которые будут возвращать данные) из моей фоновой задачи C ++?

Я создал очень пример — я хотел бы запустить RunTheFunction и RunAnotherFunction из моей фоновой задачи C ++.

public class StackOverFlowExampleClass()
{
public string Name { get; set; }
public string Value { get; set; }
}

public class StackOverFlowExampleClass2()
{
public string UpperString { get; set; }

}

public async Task<StackOverFlowExampleClass> RunTheFunction(int ParameterValue)
{
StackOverFlowExampleClass overflowClass = new StackOverFlowExampleClass();
overflowClass.Name = "Stack Overflow";
overflowClass.Value = 1 + ParameterValue;

// DO SOME COOL ADVANCED HTTP STUFF
return overflowClass;
}

public async Task<StackOverFlowExampleClass> RunAnotherFunction(string ExampleString)
{
StackOverFlowExampleClass2 overflowClass2 = new StackOverFlowExampleClass2();
overflowClass2.UpperString = ExampleString.ToUpper();

return overflowClass2;
}

В обычной фоновой задаче C # я бы сделал это:

StackOverFlowExampleClass SFClass = await stackoverflowexample.RunTheFunction(10);
StackOverFlowExampleClass2 SFClass = await stackoverflowexample.RunAnotherFunction("stackoverflow");
///// render SFClass.Value + SFClass.Name as a PNG
///// set tile title to SFClass.UpperString

Как мне сделать это в C ++?

4

Решение

Вы можете посмотреть в Компилятор Visual C ++ ноябрь 2013 CTP, некоторые изящные примеры, чтобы сделать вещи как:
__await FileIO :: WriteTextAsync (файл, файл-> Имя);

Это пока не выглядит так хорошо, и, вероятно, в будущих версиях появятся стандартные, новые и лучшие (по крайней мере, стандартные) способы сделать это.

0

Другие решения

Вы можете попробовать использовать COM для этого (хотя я не уверен, что это хорошо подходит):

Сторона C #:

using System;
using System.Runtime.InteropServices;

namespace CSharp
{
[Guid("62D276EB-FABE-4c0e-BF59-7D0799DEC029")]
[ComVisible(true)]
public interface IExampleClass
{
string Name { get; set; }
int Value { get; set; }
}

[ClassInterface(ClassInterfaceType.None)]
[Guid("4E196599-F1C5-4447-84F4-E46FC1C16105")]
[ComVisible(true)]
public class ExampleClass : IExampleClass
{
public ExampleClass()
{ }

public string Name { get; set; }
public int Value { get; set; }
}

[Guid("72D276EB-FABE-4c0e-BF59-7D0799DEC020")]
[ComVisible(true)]
public interface IExampleClass2
{
string UpperString { get; set; }
}

[ClassInterface(ClassInterfaceType.None)]
[Guid("6712709D-8913-4911-8ABB-BFB4865D4E9F")]
[ComVisible(true)]
public class ExampleClass2 : IExampleClass2
{
public ExampleClass2()
{ }

public string UpperString { get; set; }
}

[Guid("1C312E27-6B09-412c-B7AA-55F4E0FBCF8C")]
[ComVisible(true)]
public interface ICSharpFunctor
{
ExampleClass RunTheFunction(int ParameterValue);
ExampleClass2 RunAnotherFunction(string ExampleString);
}

[ClassInterface(ClassInterfaceType.None)]
[Guid("9B8FAFEA-64EB-493f-95CB-B0B0EDEBADC2")]
[ComVisible(true)]
public class CSharpFunctor : ICSharpFunctor
{
public CSharpFunctor()
{ }

public ExampleClass RunTheFunction(int ParameterValue)
{
ExampleClass instance = new ExampleClass();
instance.Name = "Stack Overflow";
instance.Value = 1 + ParameterValue;
return instance;
}

public ExampleClass2 RunAnotherFunction(string ExampleString)
{
ExampleClass2 instance = new ExampleClass2();
instance.UpperString = ExampleString.ToUpper();
return instance;
}
}
}

Вы должны взять код C # и сгенерировать файл сборки, манифеста и tlb для импорта в код C ++.

Сторона C ++:

using namespace CSharpCOM;
ICSharpFunctorPtr pCSharp;
HRESULT hr = pCSharp.CreateInstance(__uuidof(CSharpFunctor));
assert(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
IExampleClassPtr e1 = pCSharp->RunTheFunction(10);
assert(e1->Value == 11);
std::string name = e1->Name;
assert(name == "Stack Overflow");
IExampleClass2Ptr e2 = pCSharp->RunAnotherFunction("stackoverflow");
std::string uc = e2->UpperString;
assert(uc == "STACKOVERFLOW");
}

Вот ссылка на полный пример (включая некоторые биты, которые я пропустил об интерфейсах.)
https://github.com/brandon-kohn/CSharpCOM

0

У вас есть несколько вариантов:

  1. Переместите код C # в компонент среды выполнения Windows.
  2. Создайте оболочку Windows Runtime Component для кода C #
  3. Сделайте код C ++ компонентом среды выполнения Windows.
  4. Создайте оболочку Windows Runtime Component для кода C ++.

После того, как вы сделали один из них, вы можете использовать компонент в C ++, C # или JavaScript, если он написан на языке, который вы используете.


Сборка компонентов среды выполнения Windows с C ++

http://channel9.msdn.com/events/Windows-Camp/Developing-Windows-8-Metro-style-apps-in-Cpp/Building-Windows-Runtime-Components-with-Cpp

Создание компонентов среды выполнения Windows в C # и Visual Basic

http://msdn.microsoft.com/en-us/library/br230301.aspx

Создание компонентов среды выполнения Windows в C ++

http://msdn.microsoft.com/en-us/library/hh441569.aspx

Хорошим примером числа 4 является SQLite-WinRT, который можно найти здесь http://sqlwinrt.codeplex.com/

0
По вопросам рекламы [email protected]