如何从用 C# 编写的 Class 库中引用用 C++ 编写的 Windows 运行时组件?
How can Windows Runtime Component written in C++ be referenced from Class Library written in C#?
我正在开发 WP8 项目,其中包括作为 C# 源代码的 class 库项目和作为 C++ 源代码的 Windows 运行时组件。有谁知道是否可以创建这样的 C# class 库来引用 Windows 运行时组件?最终的结果应该是.NET 程序集和.WIMND/.DLL 运行时组件可以用于应用程序。目前我无法构建 class 库,因为它没有看到 Windows 运行时组件,即使我将它添加到项目中也是如此。
更具体。例如,我有 MyNs.MyClass.MyMethod(),它在 C++ 运行时组件中定义并从 C# class 库中使用。目前,由于缺少方法,我无法编译 C#,尽管我有 windows 运行时组件项目附加到同一解决方案。
尽管我插话是因为这不是我的区域,但我还是尝试使用谷歌搜索 "c# call windows runtime component"。似乎有很多hits/examples,例如第一个是 https://msdn.microsoft.com/en-us/library/hh755833.aspx.
这对你没有帮助吗?
我通过将对 Windows 运行时组件的引用手动添加到 C# class 库 .csproj 文件中解决了这个问题,如下所示
...
<ItemGroup>
<Reference Include="WindowsRuntimeComponent.winmd" />
</ItemGroup>
...
我设法制作了一个 C++ WRL 项目,并通过以正常方式添加引用,在该项目中使用了 C# 项目中的 class。 Wrl 项目(不是 C++/CX,它也可以工作)是使用我在网上某处找到的一些 WRL 模板制作的。 wrl项目要求我做一个.idl来定义接口,并生成了它的.dll和.winmd。以下是一些代码,供那些正在与此类事情作斗争的人使用:
世界class:
#include "pch.h"
#include "WrlTestClass2_h.h"
#include <wrl.h>
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
namespace ABI
{
namespace WrlTestClass2
{
class WinRTClass: public RuntimeClass<IWinRTClass>
{
InspectableClass(RuntimeClass_WrlTestClass2_WinRTClass, BaseTrust)
public:
WinRTClass()
{
}
// http://msdn.microsoft.com/en-us/library/jj155856.aspx
// Walkthrough: Creating a Basic Windows Runtime Component Using WRL
HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value)
{
if (value == nullptr)
{
return E_POINTER;
}
*value = a + b;
return S_OK;
}
};
ActivatableClass(WinRTClass);
}
}
使用这个class的C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
namespace CSharpClientToWrl
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
WrlTestClass2.WinRTClass _winRtTestClass = new WrlTestClass2.WinRTClass();
int _answer = _winRtTestClass.Add(4, 6);
Assert.AreEqual(_answer, 10);
}
}
}
wrl项目的.idl文件:
import "inspectable.idl"; import "Windows.Foundation.idl";
#define COMPONENT_VERSION 1.0
namespace WrlTestClass2 {
interface IWinRTClass;
runtimeclass WinRTClass;
[uuid(0be9429f-2c7a-40e8-bb0a-85bcb1749367), version(COMPONENT_VERSION)]
interface IWinRTClass : IInspectable
{ // http://msdn.microsoft.com/en-us/library/jj155856.aspx // Walkthrough: Creating a Basic Windows Runtime Component Using WRL HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
}
[version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
runtimeclass WinRTClass
{
[default] interface IWinRTClass;
} }
我正在开发 WP8 项目,其中包括作为 C# 源代码的 class 库项目和作为 C++ 源代码的 Windows 运行时组件。有谁知道是否可以创建这样的 C# class 库来引用 Windows 运行时组件?最终的结果应该是.NET 程序集和.WIMND/.DLL 运行时组件可以用于应用程序。目前我无法构建 class 库,因为它没有看到 Windows 运行时组件,即使我将它添加到项目中也是如此。
更具体。例如,我有 MyNs.MyClass.MyMethod(),它在 C++ 运行时组件中定义并从 C# class 库中使用。目前,由于缺少方法,我无法编译 C#,尽管我有 windows 运行时组件项目附加到同一解决方案。
尽管我插话是因为这不是我的区域,但我还是尝试使用谷歌搜索 "c# call windows runtime component"。似乎有很多hits/examples,例如第一个是 https://msdn.microsoft.com/en-us/library/hh755833.aspx.
这对你没有帮助吗?
我通过将对 Windows 运行时组件的引用手动添加到 C# class 库 .csproj 文件中解决了这个问题,如下所示
...
<ItemGroup>
<Reference Include="WindowsRuntimeComponent.winmd" />
</ItemGroup>
...
我设法制作了一个 C++ WRL 项目,并通过以正常方式添加引用,在该项目中使用了 C# 项目中的 class。 Wrl 项目(不是 C++/CX,它也可以工作)是使用我在网上某处找到的一些 WRL 模板制作的。 wrl项目要求我做一个.idl来定义接口,并生成了它的.dll和.winmd。以下是一些代码,供那些正在与此类事情作斗争的人使用:
世界class:
#include "pch.h"
#include "WrlTestClass2_h.h"
#include <wrl.h>
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
namespace ABI
{
namespace WrlTestClass2
{
class WinRTClass: public RuntimeClass<IWinRTClass>
{
InspectableClass(RuntimeClass_WrlTestClass2_WinRTClass, BaseTrust)
public:
WinRTClass()
{
}
// http://msdn.microsoft.com/en-us/library/jj155856.aspx
// Walkthrough: Creating a Basic Windows Runtime Component Using WRL
HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value)
{
if (value == nullptr)
{
return E_POINTER;
}
*value = a + b;
return S_OK;
}
};
ActivatableClass(WinRTClass);
}
}
使用这个class的C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
namespace CSharpClientToWrl
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
WrlTestClass2.WinRTClass _winRtTestClass = new WrlTestClass2.WinRTClass();
int _answer = _winRtTestClass.Add(4, 6);
Assert.AreEqual(_answer, 10);
}
}
}
wrl项目的.idl文件:
import "inspectable.idl"; import "Windows.Foundation.idl";
#define COMPONENT_VERSION 1.0
namespace WrlTestClass2 {
interface IWinRTClass;
runtimeclass WinRTClass;
[uuid(0be9429f-2c7a-40e8-bb0a-85bcb1749367), version(COMPONENT_VERSION)]
interface IWinRTClass : IInspectable
{ // http://msdn.microsoft.com/en-us/library/jj155856.aspx // Walkthrough: Creating a Basic Windows Runtime Component Using WRL HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
}
[version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
runtimeclass WinRTClass
{
[default] interface IWinRTClass;
} }