-1

This issue is driving me up the wall... Just saying.

My company has a legacy C++ library and I have been tasked to create a .NET wrapper.
I have no experience of C++ or P/Invoke so to start with I am trying a simple method.

I have read the official documentation and I have also found a nice tutorial.
However, I have discovered that the target .NET framework of the consuming app makes a difference.
The P/Invoke code from the tutorial works fine but I have noticed that he is targeting .NET Framework 4 Client Profile.
If I place break points then they are hit and everything works as expected, if I target a framework higher than 4 then the program crashes without exception.

I have a really simple method defined in C++:
framework.h

extern "C" {
    API char* SayHello();
}

dllmain.cpp

char* SayHello() {
    return (char*)"Hello";
}

C#

        [DllImport("PInvokeTest.dll")]
        public static extern string SayHello();

(I have tried setting CallingConvention and CharSet on the attribute in different combinations, I have managed to get Chinese characters, but nothing working higher than Framework 4)

My C++ project has API=__declspec(dllexport) it Preprocessor Definitions set and Calling Convention is _stdcall (\Gz) (I have also tried _cdecl).
The C# project works fine on Framework 4, when I change to anything above that then it just exits without exception.
I have also found Dependencies GUI that is showing me that SayHello is indeed there.

Our company uses 4.6.1, I also came across this article which lead me to PInvokeStackImbalance but that doesn't do anything in my case.

Any help would be greatly appreciated.
I could create a temp GitHub repo if needed.

Luke T O'Brien
  • 2,565
  • 3
  • 26
  • 38

1 Answers1

0

Now that I know it is a string issue I did a little searching and I found this SO question.
So in the end I used the BSTR approach.

BSTR SayHello() {
    return ::SysAllocString(L"Hello");
}
        [DllImport("DBReplicator.Lib.dll")]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static extern string SayHello();

... Still don't know how I managed to get Chinese characters though.

Luke T O'Brien
  • 2,565
  • 3
  • 26
  • 38
  • `BSTR` support the full Unicode range. – xanatos Jan 22 '21 at 13:05
  • 1
    Some time ago I had prepared a full-samples solution about marshalling strings between C/C++ and C#, both for .NET and .NET Framework... The samples are wholly undocumented, but quite complete. You can take a look at https://github.com/xanatos/CSharpCPlusPlusInteropSamples – xanatos Jan 22 '21 at 13:19