2017-10-11 206 views
0

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

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#代码的最后一行时,编译器会引发异常: '跑' 不被支持的语言

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

+0

它应该使用'^'。它也应该使用'^%'并在C#中使用'ref'关键字。请显示你失败的尝试。 –

+0

当使用'^','^%'或'%^'时,cli编译器会抛出:'.do_it'的左边必须有class/struct/union。 –

+1

'^'是'*'管理的等价物。你需要使用' - >',而不是'.'。 –

回答

0

我假设你是从C#得到这个错误,而不是从C++/CLI “不被支持的语言”。

public ref class do_something 

void run(do_something% doer) 

C#不支持此组合: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; 
};