dotnet / corert

This repo contains CoreRT, an experimental .NET Core runtime optimized for AOT (ahead of time compilation) scenarios, with the accompanying compiler toolchain.

Home Page:http://dot.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question about Marshalling of data structures across C++/C#

darderik opened this issue · comments

commented

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.

commented

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