【问题标题】:C++/CLI: functions inherited from template class are not visible in C#C++/CLI:从模板类继承的函数在 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 模板中的许多函数都是重载的运算符……

标签: c# .net visual-studio-2010 c++-cli


【解决方案1】:

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

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

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

void phony()
{
    auto vec = gcnew Vector3fP();
    vec->foo();
}

【讨论】:

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

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

template ref class FixedNP<3, float>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2014-07-15
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2016-12-30
    相关资源
    最近更新 更多