C++/CLI:从模板类继承的函数在 C# 中不可见

Posted

技术标签:

【中文标题】C++/CLI:从模板类继承的函数在 C# 中不可见【英文标题】:C++/CLI: functions inherited from template class are not visible in C# 【发布时间】:2011-12-13 19:30:08 【问题描述】:

我很难弄清楚如何使父类函数在 C# 中可见。

假设我有一个模板类,它定义了一个函数 foo()

template <int Dim, typename Type>
public ref class FixedNP

public:
  float foo() return 1;;
;

然后我有一个继承自 FixedNP 模板的类:

public ref class Vector3fP : public FixedNP<3, float>


当我尝试从 C# 调用 foo() 函数时,例如。

Vector3fP bar = new Vector3fP();
bar.foo();

它说函数 Vector3fP 不包含 foo 的定义。

当我将 foo() 的定义移动到 Vector3fP 类时,它工作正常。然而这在实际代码中是不可行的,因为 FixedNP 模板包含相当多的函数,这些函数应该从大约 4 个不同的类继承。

在网上搜索了一番,发现添加了

using FixedNP<3, float>::foo;

Vector3fP 为某人解决了类似的问题。但是在我的情况下,它只会导致另一个错误,这次是在编译 C++/CLI 代码时:

错误 C3182:“Vector3fP”:成员使用声明或访问声明在托管类型中是非法的

有什么建议可以让我的函数在 C# 中可见吗?

【问题讨论】:

模板没有外部链接。不在 C++ 中,也不在 C++/CLI 中。您必须使用 generic 关键字。 int Dim 不会飞。 msdn.microsoft.com/en-us/library/8z2kbc1y.aspx 我知道,这就是我从模板继承“常规”类的原因之一。 我也很确定我在这里不想要泛型。首先我希望在编译时完成,其次我真的需要 参数是 int,因为我稍后将它用作模板参数。 嗯,根据 MSDN,它们可以被管理:msdn.microsoft.com/en-us/library/ms177213.aspx 此外,当尝试混合原生代码和托管代码时,VS 会告诉你。 我刚刚找到了一个部分解决方案——如果我在 FixedNP::foo() 声明中添加 virtual 关键字,它就可以工作。不幸的是,这对静态函数没有用。这是一个相当大的问题,因为 FixedNP 模板中的许多函数都是重载的运算符…… 【参考方案1】:

我认为他们的关键在于Managed Templates on MSDN 的声明:

如果模板未实例化,则不会在元数据中发出。如果模板被实例化,只有引用的成员函数才会出现在元数据中。

这意味着未在 C++ 代码中使用的函数将不会出现在生成的 DLL 中,并且您将无法从 C# 中使用它们。要解决此问题,您可以在 C++ 代码中添加一个虚假函数,该函数引用该函数:

void phony()

    auto vec = gcnew Vector3fP();
    vec->foo();

【讨论】:

非常感谢,这对您有帮助!不知何故,我错过了文档中的那部分。我想这将迫使我创建一个合适的测试套件。 你的答案很神奇......但由于某种原因,我尝试使用的功能是“由于其保护级别而无法访问”,但它是公共的 =[ 我已经成功使用反射 =]【参考方案2】:

您可以通过添加以下行来实例化整个模板类而无需添加虚假方法。

template ref class FixedNP<3, float>;

【讨论】:

以上是关于C++/CLI:从模板类继承的函数在 C# 中不可见的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 C# 中从本机 C++ 类创建变量?

抽象类中的私有非抽象成员和继承 C#

从 C++/CLI 调用 C# dll 函数

C++/CLI 包装器尝试使用 MFC CObject 继承

你啥时候以及为啥要封课?

从 C++ 调用 C# dll(MSVC 编译器)