Saeid Zarrinmehr
Saeid Zarrinmehr

Reputation: 11

"method" is not supported by the language

My solution in VS2010 has a CLI project which is referenced in a c# project. I have an abstract class in CLI named do_something. In C# I inherit DoSomething class from it. I want to run the c# implementation from c++ by passing the c# implementation as an abstract class argument but the "not supported by the language" exception is thrown.

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);

The c++ project compiles but when compiling the last line of c# code the compiler throws an exception: 'run' is not supported by the language

NOTE: Previous solutions in stack overflow are not helpful! Calling run.do_it() works fine in c#. Finally, the CLI compiler does not like using '^' or '&' to pass an argument to the run method by reference.

Upvotes: 1

Views: 697

Answers (1)

David Yaw
David Yaw

Reputation: 27864

"not supported by the language"

I'm assuming that you're getting this error from C#, not from C++/CLI.

public ref class do_something

void run(do_something% doer)

This combination is not supported by C#: A tracking reference to a value of a reference type.

Since it's a reference type, do_something by itself in C# is equivalent to do_something^ in C++/CLI. Declaring a method with a ref do_something parameter in C# makes it do_something^% in C++/CLI. For reference types, that's all that C# supports.

C++/CLI does support using a ref class as a value: do_something by itself gives you stack semantics, and you can pass it using do_something% for a tracking reference, but neither of these is used in C#.

The proper way to pass around a ref class is with ^, and initialize variables with gcnew. This is the way that other .Net languages do it, so you need to follow their rules if you want to be callable from them. And as you noted in the comments, switching to ^ fixed your problem.


Other notes:

That's the C++ way to declaring an abstract class, which I wasn't even aware was still supported in C++/CLI. If you want to declare it in the managed way (which I would recommend), use the keyword abstract on the class and the method.

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

Upvotes: 1

Related Questions