3D Vector structure from c++ to C#

2019-05-19 23:41发布

问题:

I'm trying to port some functionality from my engine from c++ to C#. I compile my engine as a dll with unmanaged c++ and only use extern "C" functions in the C# wrapper.

I have various functions that take and return Vector3df. This is defined as

typedef Vector3d<f32> Vector3df;

and f32 is a actually a float. The class itself has nothing more than some members called x y and z and a lot of methods.

I can rewrite the whole class in C#, that's not a problem but is there anyway in which the 2 could be matched?

Let's take for example the following functions:

extern "C" void SetColor(Vector3df color)
extern "C" Vector3df GetColor()

I would like to have something like this in C#:

[DllImport("Engine.dll", EntryPoint = "SetColor", CallingConvention = CallingConvention.Cdecl)]
static extern void SetColor(Vector3df color);
[DllImport("Engine.dll", EntryPoint = "GetColor", CallingConvention = CallingConvention.Cdecl)]
static extern Vector3df GetColor();

Is there anyway in which I could make code similar to this work?

Note that I'm not by any means a C# guru.I'm lost when it comes to marshaling. I'm mostly doing this to make a map editor for my game without having to learn Qt or wxWidgets.

Thank you!

回答1:

All you need to do is define a C# structure that has an equivalent binary layout to the one expected by the c++ dll. Assuming only x,y,z with no packing, that's just...

[StructLayout(LayoutKind.Sequential)] //Required, as default layout is Auto
struct Vector3df {
    public float x, y, z;
}

That should work with the C and C# function signatures you've given. The difficulty arises if you wish to invoke any method on the Vector3df class, because you cannot p/invoke C++ class methods. You need to wrap each of the methods as a plain C function as you've done with the Set/GetColor.

It ends up being a lot of work if you're trying to import a big library, and might be simpler to use C++/CLI to create the wrapper. Another option might be to investigate using cxxi, but I have no experience using this.



回答2:

The simplest way might be to just create another C++/CLI wrapper DLL where you do the conversion between unmanaged and managed C++ classes.