Passing a structure from C # to C ++

I have the following structure in C ++

extern "C" __declspec(dllexport) struct SnapRoundingOption { double PixelSize; bool IsISR; bool IsOutputInteger; int KdTrees; }; 

And this is my function declaration in C ++:

 extern "C" __declspec(dllexport) void FaceGenerationDummy(SnapRoundingOption snapOption); 

This is my corresponding C # code:

 [StructLayout(LayoutKind.Sequential, Pack = 1)] //I also tried not to specify Pack, but the same error occurred. public struct SnapRoundingOption { public double PixelSize; public bool IsISR; public bool IsOutputInteger; public int KdTrees; public SnapRoundingOption(double pixelSize, bool isISR, bool isOutputInt, int kdTrees) { PixelSize = pixelSize; IsISR = isISR; IsOutputInteger = isOutputInt; KdTrees = kdTrees; } public SnapRoundingOption(double pixelSize) :this(pixelSize, false, false, 1) { } } [DllImport("Face.dll")] public static extern void FaceGenerationDummy(SnapRoundingOption snapRoundingOption); 

However, when I call FaceGenerationDummy with this test:

  [Test] public void DummyTest() { SimpleInterop.FaceGenerationDummy(new SnapRoundingOption(10, true, false, 1)); } 

I found that KdTrees is 0 in C ++ and not 1 as passed.

What have I done wrong?

Edit: I am using Visual Studio 2008 on 32-bit Windows 7, not sure if this helps.

Edit 2: Both sizeof(SnapRoundingOption) return the same number, 16.

+8
c ++ c # interop
source share
2 answers

The problem is how you sort the bool fields. These are single bytes in C ++ and therefore they need to be sorted like this:

 [StructLayout(LayoutKind.Sequential)] public struct SnapRoundingOption { public double PixelSize; [MarshalAs(UnmanagedType.U1)] public bool IsISR; [MarshalAs(UnmanagedType.U1)] public bool IsOutputInteger; public int KdTrees; } 

Combine this on the C ++ side:

 struct SnapRoundingOption { double PixelSize; bool IsISR; bool IsOutputInteger; int KdTrees; }; 

I removed the packaging settings so that the structures have a natural platform match.

You must also ensure that your consent agreements are in agreement. Be that as it may, C ++ code seems to use cdecl , and C # code uses stdcall . for example

 [DllImport("Face.dll", CallingConvention=CallingConvention.Cdecl)] 

aligned both sides of the interface.

+12
source share

bool NOT blittable ! Its default marshaling is Win32 bool (which is 4 bytes), not bool (it's 1 byte)!

+3
source share

All Articles