Search code examples
c#c++clr

not supported by the language


I code regularly in C++, and for the specific project I'm working on right now, I'm writing a C++ lib whose methods are to be used in a C# lib, whose methods are to be used in a C# app.

I use Microsoft Visual Studio 2017 on Windows 10.

I created a solution with 3 projects :

  1. A C++/CLI dynamic lib (New Project => Visual C++ => CLR => Class Library)
  2. A C# lib (New Project => Windows Classic Desktop => Class Library (.NET Framework))
  3. And a C# app (New Project => Windows Classic Desktop => Console App (.NET Framework))

For now, I'm just trying to make the 3 projects communicate together, and I seem to have problems between the C++ lib and the C# lib.

The code in my C++ lib is the following ;

cppLib.h

#pragma once
#include <string>

using std::string;

using namespace System;

namespace cppLib {
    public ref class cppClass
    {
    public:
        static string test();
        static double add(double arg1, double arg2);
    };
}

cppLib.cpp

#include "cppLib.h"

namespace cppLib {
    string cppClass::test() {
        return "Hello World from C++ lib.";
    }

    double cppClass::add(double arg1, double arg2) {
        return arg1 + arg2;
    }
}

The code in my C# lib is the following :

Wrapper.cs

using cppLib;

namespace CsWrapper
{
    public class Wrapper
    {
        //static public string TestCppLib()
        //{
        //    return cppClass.test();
        //}

        static public double Add(double arg1, double arg2)
        {
            return cppClass.add(arg1, arg2);
        }

        public string WrapperTest()
        {
            return "Hello World from C# lib.";
        }
    }
}

As is, this code builds without errors nor warnings. So I can call my static double add(double arg1, double arg2); method from my C++ lib in my C# lib method static public double Add(double arg1, double arg2), BUT if I try to uncomment the following code in Wrapper.cs :

        //static public string TestCppLib()
        //{
        //    return cppClass.test();
        //}

I get the 'cppClass.test(?)' is not supported by the language error message :

Severity    Code        Description                                             Project     File                                        Suppression State
Error       CS0570      'cppClass.test(?)' is not supported by the language     CsWrapper   D:\documents\...\CsWrapper\Wrapper.cs       Active

What does it mean? How can I call one method from my C++ lib in my C# lib without problem, but the other I can't? My public string WrapperTest() method returns a string all right that I can use in my C# app (it works, I can display it), so why can't I call that specific C++ method in my C# lib? It's also really my first time coding in C#.


Solution

  • In C++/CLI, a string cannot be returned as a native C++ template type if the method is to be used by a C# app / lib, because the C# code won't know how to use it.

    The managed (.Net variant) of the type has to be used; for a C++ string, it's a String^. The ^ indicates that it is a ref class (managed) pointer.

    The code becomes :

    cppLib.h

    #pragma once
    #include <string>
    
    using std::string;
    
    using namespace System;
    
    namespace cppLib {
        public ref class cppClass
        {
        public:
            static String^ test();
            static double add(double arg1, double arg2);
        };
    }
    

    cppLib.cpp

    #include "cppLib.h"
    
    namespace cppLib {
        String^ cppClass::test() {
            return "Hello World from C++ lib.";
        }
    
        double cppClass::add(double arg1, double arg2) {
            return arg1 + arg2;
        }
    }
    

    The rest stays the same.