我在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方法。
答案 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;
};