Question about Marshalling of data structures across C++/C#
darderik opened this issue · comments
Hello, following the solution provided to the issue #6984 , I tried playing around with the return of data structures from C++ to C#, as i couldn't find an issue related to this kind of operation, I thought about opening one in order to receive a few heads-up on the topic.
C++ Code
struct myStruct {
int ok;
string testStr;
} ;
extern "C" myStruct entry() {
myStruct myStu;
myStu.ok = 1;
myStu.testStr = "hello";
return myStu;
}
C# Code
namespace CppInterop
{
class Program
{
static void Main(string[] args)
{
dynamic ok = entry();
}
[DllImport("*")]
public extern static dynamic entry();
}
}
As expected, i get this error
Unhandled Exception: System.Exception: Method '[CppInterop]CppInterop.Program.entry()' requires marshalling that is not yet supported by this compiler.
at CppInterop.Program.entry() + 0x30
at CppInterop!<BaseAddress>+0x1e9b2d
Aborted
I was wondering if there was another way (as I know that dynamic isn't aot friendly at all) to pass data structures (or objects) back from cpp , in the particular case that i know exactly how is the passed object structured.
Thank you for the help 👍
extern "C" myStruct entry()
You can't pass a myStruct
with a std::string
to anything, really. AFAIK the memory layout of std::string
is not even stable across different versions of the C++ standard libraries (a DLL compiled with e.g. Visual C++ 6.0 would have a hard time consuming this mystruct coming from an EXE compiled with Visual Studio 2019).
You have to use C types such as char*
.
public extern static dynamic entry();
This means COM marshalling - the C++ side would have to return the value as a COM interface for this to work. CoreRT doesn't support COM.
I suggest reading up on p/invoke in general. This question is not really CoreRT related.
Clear enough. I read the error so I thought that there was something in the work in order to 'marshal' complex data structures(in this case COM Interfaces). thank you