"方法"

时间:2017-10-11 20:31:33

标签: c# c++-cli

我在VS2010中的解决方案有一个CLI项目,该项目在c#项目中引用。我在CLI中有一个名为do_something的抽象类。在C#中,我从中继承了DoSomething类。我希望通过将c#实现作为抽象类参数传递来运行c ++中的c#实现,但是#34;语言不支持#34;抛出异常。

CLI / C ++

//abstract class
public ref class do_something{
  public:
  virtual void do_it()=0;
};
//using an implementation of the abstract class
public ref class cpp_caller{
  public:
  void run(do_something% doer){
    cout<<"run c# from c++"<<endl;
    doer.do_it();
  }
};

c#

//implementation of abstract class
class DoSomething : do_something
{
  public override void do_it()
  {
    Console.WriteLine("call from c#");
  }
}
//inside main
DoSomething csharp_implementation = new DoSomething();
cpp_caller caller = new cpp_caller();
caller.run(csharp_implementation);

c ++项目编译但是在编译最后一行c#代码时,编译器会抛出异常:&#39;运行&#39;语言不支持

注意:堆栈溢出的先前解决方案没有帮助!调用run.do_it()在c#中运行正常。最后,CLI编译器不喜欢使用&#39; ^&#39;或者&#39;&amp;&#39;通过引用将参数传递给run方法。

1 个答案:

答案 0 :(得分:0)

  

“语言不支持”

我假设您从C#获得此错误,而不是来自C ++ / CLI。

public ref class do_something

void run(do_something% doer)

C#不支持此组合:对引用类型值的跟踪引用。

由于它是引用类型,因此在C#中do_something本身相当于C ++ / CLI中的do_something^。在C#中声明具有ref do_something参数的方法会使其在C ++ / CLI中成为do_something^%。对于引用类型,这就是C#支持的所有内容。

C ++ / CLI确实支持将ref类用作值:do_something本身为您提供堆栈语义,您可以使用do_something%传递它以进行跟踪引用,但这些都不会被使用在C#中。

传递ref类的正确方法是使用^,并使用gcnew初始化变量。这是其他.Net语言执行此操作的方式,因此如果您希望从中调用它们,则需要遵循其规则。正如您在评论中指出的那样,切换到^修复了您的问题。

其他说明:

这是C ++声明抽象类的方法,我甚至不知道它仍然在C ++ / CLI中得到支持。如果您想以托管方式(我建议)声明它,请在类和方法上使用关键字abstract

public ref class do_something abstract
{
public:
    virtual void do_it() abstract;
};