【问题标题】:How can Windows Runtime Component written in C++ be referenced from Class Library written in C#?如何从 C# 编写的类库中引用 C++ 编写的 Windows 运行时组件?
【发布时间】:2017-03-23 16:53:35
【问题描述】:

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

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

【问题讨论】:

  • 项目 + 添加引用,解决方案节点,勾选你的 C++ 项目。
  • 类库还是可移植类库?如果是后者,你选择了哪些目标?
  • 我选择了类库 (Windows Phone 8.0)。无论如何,我通过手动添加对 .winmd 文件的引用解决了这个问题。

标签: c# c++ windows-phone-8 class-library


【解决方案1】:

虽然我因为这不是我的领域而加入进来,但我尝试在谷歌上搜索“c# call windows runtime component”。似乎有很多命中/例子,例如第一个是https://msdn.microsoft.com/en-us/library/hh755833.aspx

这对你没有帮助吗?

【讨论】:

  • 很遗憾没有。这些示例中的大多数都解释了如何从 App 调用组件。在我的情况下,它不是一个应用程序,它是一个需要作为 .NET 程序集 DLL 交付的类库。
  • 明白,抱歉没有帮助。鉴于此,也许您可​​以添加“类库”或类似于此问题的标签?
【解决方案2】:

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

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

【讨论】:

  • 相对于.csproj.winmd 文件在哪里?这是唯一的步骤,还是除了将.winmd 添加到参考部分之外?
  • Windows 运行时组件由两部分组成 - 本机 DLL 和将本机部分映射到托管接口的包装 WINMD 代码。仅用于编译,将 WINMD 放入 C# 类库 DLL 所在的同一文件夹中就足够了。为了正常运行,所有组件都应存在于同一文件夹中 - C# 类库 DLL、C++/CX WINMD 托管部分和 C++/CX 本机 DLL。
  • 对上一条评论的一些澄清:.winmd 文件不包含任何(包装器)代码。它们仅包含元数据,重新使用 .NET 的文件格式。编译器使用元数据发出代码以访问 Windows 运行时组件。
【解决方案3】:

我设法创建了一个 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;
    } }

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2011-03-08
    • 1970-01-01
    • 2019-02-13
    • 2018-11-04
    • 1970-01-01
    相关资源
    最近更新 更多