【问题标题】:Making C# compatible interface for C++/CLI managed type为 C++/CLI 托管类型制作 C# 兼容接口
【发布时间】:2017-12-11 14:56:36
【问题描述】:

我有一些本机 C/C++ 函数,我正在 C++/CLI (Visual Studio 2015) 中为其创建托管包装器。

特别是,我的一种托管类型如下所示:

public ref class MyClass abstract : public IMyClass
{
public:
    virtual void SomeMethod(ID id);
}

类型ID定义为:

typedef unsigned long ID;

由于单元测试的目的,我想在另一个 C# 程序集上创建与我的包装器类型兼容的接口,我想与 C++/CLI 世界分开,所以我制作了这个接口:

public interface IMyClass
{
    void SomeMethod(uint id);
}

当我尝试编译托管 C++/CLI 程序集时,我收到错误消息,提示我应该为“void SomeMethod(unsigned int)”提供合适的实现。

我在界面上使用了 uint 类型,因为根据 MSDN documentation,unsigned long 被转换为托管类型 System.UInt32 (uint),但似乎(相反)使用 unsigned long 来实现 uint 是不可能的。

你们中有人遇到过同样的问题吗?你知道如何解决这个问题吗? 是否可以告诉 C++/CLI 编译器我的 unsigned long 应该被视为 uint 类型?

我无法更改 ID 定义,因为它是本机库的一部分并且被其他函数广泛使用。

【问题讨论】:

  • 不是兼容接口。您可能得到了正确的命名空间和类型名称,但这在 .NET 中还不够好。类型标识还包括它来自的程序集。强大的 DLL 地狱对策。您的测试程序必须使用完全相同的接口类型,如果您还没有这样做,请添加对定义它的程序集的引用。
  • 您似乎在使用 C#,但只是作为一个提示:UInt32 不符合 CLS。其他 .NET 语言可能无法理解。
  • 我明白这一点,我知道这不是程序集的问题,而是编译器如何在本机/托管类型之间进行转换,反之亦然。令我困惑的是,“unsigned long”被编译为 UInt32,但是当编译器看到 UInt32 的接口但实现为“unsigned long”时,它们是不兼容的。

标签: c# .net interface c++-cli


【解决方案1】:

如有疑问,请明确说明。

我建议您在任何地方都使用System::UInt32:当您定义接口类型时,以及当您实现它时。这将消除定义和实现之间任何细微的不匹配。

在 C++ 领域,int 和 long 是不同的类型,即使它们的大小相同。实现接口时,参数类型必须完全匹配,看起来 32 位 int 和 32 位 long 之间的细微差别会有所不同。

【讨论】:

  • 正如我之前所说...我无法更改 ID 的定义(无符号长)。我只能更改我正在尝试制作的 C# 接口的定义。换句话说......我似乎无法在 .NET 中为该类型 (ID) 制作兼容的接口?
  • 对所有 .Net 相关代码(接口定义和实现)使用System::UInt32。如果它是其他地方的 32 位 unsigned long,那很好,因为它会在您调用该方法时进行简单的转换,但在您实现接口时它必须完全匹配。
  • 谢谢@david-yaw,效果很好。不幸的是,我的代码库太大,无法在所有地方进行这些更改。不得不走不同的路线,但我接受了这个答案。
猜你喜欢
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多