如何从用C#编写的类库中引用用C++编写的Windows运行时组件

How can Windows Runtime Component written in C++ be referenced from Class Library written in C#?

本文关键字:C++ Windows 运行时 组件 引用 类库      更新时间:2023-10-16

我正在开发WP8项目,该项目包括作为C#源代码的类库项目和作为C++源代码的Windows运行时组件。有人知道是否可以创建这样一个引用Windows运行时组件的C#类库吗?最终的结果应该是.NET程序集和可用于应用程序的.WIMND/.DLL运行时组件。目前我无法构建类库,因为它看不到Windows运行时组件,即使我将其添加到项目中。

更具体一点。比如说,我有MyNs.MyClass.MyMethod(),它在C++运行时组件中定义,并从C#类库中使用。目前,由于缺少方法,我无法编译C#,尽管我有windows运行时组件项目附加到同一解决方案。

尽管我插话是因为这不是我的领域,但我还是尝试在谷歌上搜索"c#call windows运行时组件"。似乎有很多点击/例子,例如第一个是https://msdn.microsoft.com/en-us/library/hh755833.aspx.

这对你没有帮助吗?

我通过在C#类库.csproj文件中手动添加对Windows运行时组件的引用来解决这个问题,如下所示

...
    <ItemGroup>
        <Reference Include="WindowsRuntimeComponent.winmd" />
    </ItemGroup>
...

我设法制作了一个C++WRL项目,并通过以正常方式添加引用,从C#项目中使用该项目中的一个类。Wrl项目(不是C++/CX,它也能工作)是使用我在网上找到的一些Wrl模板制作的。wrl项目要求我制作一个.idl来定义接口,并生成了它的.dll和.winmd

Wrl类:

#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);
    }
}

使用这个类的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;
    } }