C# 如何从C++;后台任务(Windows通用应用程序)?
我正在将我的应用程序(使用自定义live tiles)重写为通用应用程序。以前,我使用第三方库来渲染这些定制的实时平铺。这个库不再受支持,所以我必须找到一种新的方法来实现这一点。看来这是目前唯一的出路,但这是在C++。我的应用程序的其余部分是C# 我的后台任务应该从公共API(例如天气)获取数据,并使用这些信息渲染实时互动程序。我已经编写了用于获取数据的类(我也在主应用程序中使用它们),但这些类是用C#编写的 现在,使用Windows运行时组件,应该可以“混合”不同的语言(对吗?)。但我如何做到这一点?(缺少混凝土样品) < > > <强>我如何调用C++函数(将返回数据)从C++背景任务< /强>?/p> <>我创建了一个非常好的示例——我想从C++后台任务运行RunTew函数和RunAsOffice函数。C# 如何从C++;后台任务(Windows通用应用程序)?,c#,c++,windows-runtime,windows-phone-8.1,win-universal-app,C#,C++,Windows Runtime,Windows Phone 8.1,Win Universal App,我正在将我的应用程序(使用自定义live tiles)重写为通用应用程序。以前,我使用第三方库来渲染这些定制的实时平铺。这个库不再受支持,所以我必须找到一种新的方法来实现这一点。看来这是目前唯一的出路,但这是在C++。我的应用程序的其余部分是C# 我的后台任务应该从公共API(例如天气)获取数据,并使用这些信息渲染实时互动程序。我已经编写了用于获取数据的类(我也在主应用程序中使用它们),但这些类是用C#编写的 现在,使用Windows运行时组件,应该可以“混合”不同的语言(对吗?)。但我如何做到
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++中实现这一点? 您可以查看一些漂亮的示例,例如:
__等待FileIO::WriteTextAsync(文件,文件->名称)
它看起来还不太好,未来版本中可能会出现标准的、不断发展的、新的和更好的(至少是标准的)实现方法。您可以尝试使用COM实现这一点(尽管我不确定它是否适合): C侧: 您必须采用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");
}
下面是一个完整示例的链接(包括我错过的一些关于接口的内容)
您有几个选择:
在你完成其中一个之后,你可以使用C++中的组件,C语言或JavaScript,如果它是用你所使用的语言编写的。
用C语言构建Windows运行时组件++ 在C#和Visual Basic中创建Windows运行时组件 在C语言中创建Windows运行时组件++
数字4的一个很好的例子是SQLite WinRT,可以在这里找到它您有什么原因不能用C#编写您的后台任务并从此调用XamlRenderingBackgroundTask吗?由于内存问题,不建议这样做。这里有一个样本,但没有成功。。代码生成了一个损坏的映像。但这不意味着你的整个问题都是“由于内存问题而不推荐使用”吗?我刚才说的是生成磁贴。。这就是占用内存的东西。如果后台任务是C++(并进行渲染),那么我想我会很好的。谢谢你的回答。我尝试了您的步骤,但生成tlb文件时遇到了问题。为此,我必须在项目属性中启用“注册COM互操作”,但此复选框变灰。输出类型设置为“类库”。您不必启用它。我创建了一个COM项目,但没有使用它。您可以设置清单,以便不必注册程序集。您正在使用哪个版本的visual studio?我可以把一个小例子放在我的github上。我已经更新了答案,包含了完整工作示例的链接。我已经安装了它,你能举个例子说明如何使用上面提到的代码吗?我对如何使用它感到困惑:(
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;
}
}
}
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");
}