Search code examples
c#structinteroppinvokemarshalling

Can I marshal data from a C/C++ struct into a C# struct with properties?


I have a C# struct which is used for interfacing with some native code. Let's say it looks like this and there's an entry point in the dll that can be used to retrieve values for this struct:

public struct MyNativeStruct 
{
    public double ExampleField;
}

[DllImport("SomeDll")]
public static extern MyNativeStruct GetMyNativeStruct();

The struct is used to get structured values out of a native dll i.e. it mirrors a struct in the dll. This is all marshalling properly, so I can use the values just fine in my .NET application.

Later on, I've come to a situation where I really need a struct (or object) that has properties rather than fields so what I really want is something that looks more like this:

struct MyNativeStruct 
{
    public double ExampleField { get; set; }
}

Now of course I could just wrap the extern method which gets the struct from the dll and then convert it to an object with properties like this:

public sealed class MyNativeClass 
{
    public double ExampleField { get; set; }
}

// Some quick and dirty function to get values from MyNativeStruct.
public static MyNativeClass GetMyNativeClass() 
{
    var nativeStruct = GetMyNativeStruct();
    return new MyNativeClass { ExampleField = nativeStruct.ExampleField };
}

But this means I will have to create 2 types for each native struct that I want to retrieve from the dll so I was hoping that there may be some nice way to just marshal the native struct into a .NET struct with properties instead of fields.

I suppose it could also be possible to create the struct with the public fields first which are backed by properties also in the struct.

Anyway, I was wondering if there was some standard, idiomatic or built-in way to marshal native struct types into C# struct types that have properties rather than public fields.


Solution

  • For anyone who comes here in future, my solution was to add the properties after the struct fields (as suggested by GSerg, David Heffernan and Simon Mourier in the comments).

    So my struct now looks a little something like this:

    struct MyNativeStruct 
    {
        private double ExampleField;
        public double ExampleProperty => ExampleField;
    }