如何从C ++后台任务(Windows Universal app)调用C#函数?

时间:2014-07-23 12:16:49

标签: c# c++ windows-runtime windows-phone-8.1 win-universal-app

我将我的应用(使用自定义动态磁贴)重写为通用应用。以前,我使用第三方库来呈现这些自定义动态磁贴。这个库不再受支持了,所以我必须找到一种新方法来实现这一点。似乎XamlRenderingBackgroundTask是目前唯一的前进方式,但这是在C ++中。我的应用程序的其余部分在C#中。

我的后台任务应该从公共API(例如天气)获取数据,并使用此信息来呈现实时图块。我已经编写了类来获取数据(我也在主应用程序中使用它们),但这些是用C#编写的。

现在,使用Windows运行时组件,应该可以“混合”#39;不同的语言(对吗?)。但是我该如何实现这一目标呢? (缺少具体样品)。

简而言之:如何从我的C ++后台任务中调用C#函数(将返回数据)

我创建了一个非常示例 - 我想从我的C ++后台任务中运行RunTheFunction和RunAnotherFunction。

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 ++中执行此操作?

3 个答案:

答案 0 :(得分:0)

您可以查看Visual C++ Compiler November 2013 CTP,一些漂亮的示例来执行以下操作:     __await FileIO :: WriteTextAsync(file,file-&gt; Name);

它看起来并不好看,很可能标准的演变,新的和更好的(至少标准的)方法将在未来的版本中出现。

答案 1 :(得分:0)

您可以尝试使用COM(虽然我不确定它是否合适):<​​/ p>

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

答案 2 :(得分:0)

您有几个选择:

  1. 将C#代码移动到Windows运行时组件中。
  2. 为C#代码
  3. 创建包装器Windows运行时组件
  4. 使C ++代码成为Windows运行时组件。
  5. 为C ++代码创建包装器Windows运行时组件。
  6. 完成其中一个之后,您可以在C ++中使用该组件,如果它是用您正在使用的语言编写的话,则使用C#或JavaScript。


    使用C ++构建Windows运行时组件

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

    使用C#和Visual Basic创建Windows运行时组件

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

    使用C ++创建Windows运行时组件

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

    第4个好例子是SQLite-WinRT,可在此处找到http://sqlwinrt.codeplex.com/