0

I'm consuming a C++/CLR DLL to my C# app and been struggling with passing byRef arguments to the native methods, as the Native code comes with "&" but the C# prompts I need to remove the "ref" (or "out") keyword. Moreover, the arguments are translates to "" in my C# and strings for e.g. cannot accept that type so I'm getting conversion error from 'string' to 'string'.

I'm using Pavel Yosifovich example code for this demo:

Managed C++ file: ManagedPerson.cpp

String^ ManagedPerson::SayHello(String^ &greet) {

marshal_context ctx;
return gcnew String(m_pNative->SayHello(ctx.marshal_as<LPCTSTR>(greet)));

}

My C# App: Main.cs

static void Main(string[] args)
    {
        var person = new ManagedPerson("Bart", 10);

        Console.WriteLine(person.SayHello("Hello "));
    }

Then I'm getting this error in my C# compilation (cause of person.SayHello):

Argument 1: cannot convert from 'string' to 'string*'

This works if I remove the "&" from the C++ code (String^ &greet) but I must send it by reference.

I've managed to use types like Int32 using IntPtr successfully (though as unsafe code) but the problem is with strings and other complex types.

Any clue will help. Thx.

Dave Gahan
  • 299
  • 2
  • 14
  • Does this answer perhaps help? [link](https://stackoverflow.com/a/6471851/3763021) – Topher Feb 27 '18 at 13:20
  • You're trying to handle the interop in the wrong place. C++\CLR and C# speak the same language, so ditch the "&" in your C++\CLR method. What does the unmanaged `SayHello` member function look like? – Mark Benningfield Feb 27 '18 at 14:08
  • Thanks. SayHello looks like this in the sample: CString NativePerson::SayHello(LPCTSTR greet) { return greet + m_Name; } In my app, I'm using std::wstring instead of CString and LPCTSTR – Dave Gahan Feb 27 '18 at 15:27
  • When removing the "&" from String^ ManagedPerson::SayHello(String^ &greet) { It works, but I get no reference to the value I'm sending... – Dave Gahan Feb 27 '18 at 15:40
  • Alright, the sample is irrelevant. _Edit your question_ to include the NativePerson class definition and the rest of the ManagedPerson class. There's not enough information to tell what's going on here. – Mark Benningfield Feb 27 '18 at 18:02

1 Answers1

0

Ok this has been solved this way:

When my string ref params in C++ code was like Foo(String^ MyStr) ,my CLR was expecting it as string*.

I had to call it like String^% in order to call it in regular Foo(ref string MyStr)

However, the MANAGED class wont pass the values to the ref params so I had to use temp params, i.e.:

Void Foo(String^ %MyStr) 
    { 
marshal_context ctx;
    std::wstring temp_MyStr = ctx.marshal_as<std::wstring>(MyStr);
    myCppClass->DoSomthing(temp_MyStr);
    MyStr = temp_MyStr.c_str();
        }

This refers also to other types such as int%, short% etc.

As for the example in the question, the solution was just replacing the "&" with "%".

String^ ManagedPerson::SayHello(String^ %greet) {

Hope this helps...

Dave Gahan
  • 299
  • 2
  • 14