Search code examples
c#c++-cliclr

Change String^ parameter passed from C# to CLR


I have a C++ library, which is getting wrapped using C++ CLI. The CLI library has a function declaration like this:

void changeString(System::String^ message)

in C# I have a string variable, which I pass like this:

string myString = "This should be gone";
CLI_Wrapper_Object.changeString(myString);

back in the CLI library I try the following:

void changeString (System::String^ message){
   message = "New Message";
}

this seems to change the value on CLI level but not on C# level. I can see that it is definitely changed through the debugger but as soon as I jump back to C# I see the old initial value again.

Other ways I tried doing it:

message = gcnew System::String("New Message");

Is it even possible to do what I try to achieve?


Solution

  • The C# equivalent of what you're trying to do is:

    public void changeString(string message)
    {
        message = "New Message";
    }
    
    string message = "Foo";
    changeString(message);
    Console.WriteLine(message); // Prints 'Foo'
    

    That won't work, because parameters in .NET are pass-by-value. If you need to change the variable that's seen by the caller, you need to declare it as ref:

    public void changeString(ref string message)
    {
        message = "New Message";
    }
    
    string message = "Foo";
    changeString(ref message);
    Console.WriteLine(message); // Prints 'New Message'
    

    The C++/CLI equivalent is %:

    void changeString (System::String^% message){
       message = "New Message";
    }
    

    Then in C#:

    changeString(ref message);