Struktura parametrów w klasie C# musi mieć takie same odbicie w nagłówku C++ . Dodatkowo obiekty (MyStep, PCB) w strukturze w klasie C# muszą być z atrybutem UnmanagedType.Struct. Dodatkowo struktura CustomerPanel w C# nie może mieć atrybutu Pack=1. W definicji funkcji cppTestStructMyCustomerPanelArray() nie ma pointera dla myCustomerPanelArray[].
Struktury w C++ (header):
typedef struct _MySinglePCB { int pcbID; int pcbNumber; int width; int height; int diagonal; bool panel; } MySinglePCB; typedef struct _MyStep { int stepX; int stepY; } MyStep; typedef struct _MyCustomerPanel { int myCounter; int id; int mySubIndex; // idzie w parze z ID int width; int height; int diagonal; MyStep step; MySinglePCB myPCB; bool located; float occupancy; } MyCustomerPanel;
Struktury w C# klasa CustomerPanel.cs:
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct PCB { public int id; public int number; public int width; public int height; public int diagonal; [MarshalAs(UnmanagedType.I1)] public bool panel; } public struct MyStep { public int stepX; public int stepY; } // nie urzywac: Pack = 1 [StructLayout(LayoutKind.Sequential)] public struct CustomerPanel { public int myCounter; public int id; public int mySubIndex; public int width; public int height; public int diagonal; [MarshalAs(UnmanagedType.Struct, SizeConst = 1)] public MyStep step; [MarshalAs(UnmanagedType.Struct, SizeConst = 1)] public PCB pcb; [MarshalAs(UnmanagedType.Bool)] public bool located; [MarshalAs(UnmanagedType.R4)] public float occupancy; }
Funkcja w C++:
HRESULT cppTestStructMyCustomerPanelArray(MyGerber * const ghw, MyCustomerPanel myCustomerPanelArray[]) { myCout("MyGerber.cpp: cppTestStructMyCustomerPanelArray()" << endl); myCout("sizeof(myCustomerPanelArray): " << sizeof(myCustomerPanelArray) << endl); myCustomerPanelArray[0].id = 19; myCustomerPanelArray[0].width = 166; myCustomerPanelArray[0].height = 255; myCustomerPanelArray[1].id = 29; myCustomerPanelArray[1].width = 299; myCustomerPanelArray[1].height = 397; myCustomerPanelArray[1].step.stepX = 2; myCustomerPanelArray[1].step.stepY = 3; }
Funkcja w C#:
private const string myDLLfile = "pcbMergerLib2.dll"; DllImport(myDLLfile, CallingConvention = CallingConvention.Cdecl, EntryPoint = "cppTestStructMyCustomerPanelArray")] internal static extern int myTestStructMyCustomerPanelArray(IntPtr hwnd, IntPtr myCustomerPanelPtr); public cppWrapper() { hwndGerber = MyGerber(); Console.WriteLine("cppWrapper(): constructor: hwndGerber: {0:x}", hwndGerber); } CustomerPanelArray myCPA = new CustomerPanelArray(); int sizeCPA = Marshal.SizeOf(typeof(CustomerPanelArray)); Console.WriteLine("sizeCPA: {0}", sizeCPA); IntPtr myCPAPtr = Marshal.AllocHGlobal(sizeCPA); Marshal.StructureToPtr(myCPA, myCPAPtr, true); myTestStructMyCustomerPanelArray(hwndGerber, myCPAPtr); // call to DLL myCPA = (CustomerPanelArray)(Marshal.PtrToStructure(myCPAPtr, typeof(CustomerPanelArray))); Marshal.FreeHGlobal(myCPAPtr); // sprawdzenie (i dziala) Console.WriteLine("cpID\t cpWidth\t cpHeight\t cpOccup\t stepX\t stepY\t pcbID\t " + "pcbNr\t pcbWidth\t pcbHeight"); for (int i = 0; i < 8; i++) // alokacja dla 8 (u)rzytkuf { Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].id); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].width); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].height); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].step.stepX); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].step.stepY); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].pcb.id); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].pcb.number); Console.Write("[{0}] {1} \t", i, myCPA.myCustPanel[i].pcb.width); Console.Write("[{0}] {1} \n", i, myCPA.myCustPanel[i].pcb.height); }
I wynik:
MyGerber.cpp: MyGerber() ctor MyMaxRectsBinPack.cpp: MyMaxRectsBinPack() ctor MyGerber.cpp: MyGerber(): mrbp: 00CBAB60 MyGerber.cpp: MyGerber_New(): MyGerberPtr: 00C7D6A8 cppWrapper(): constructor: hwndGerber: 13096616 -- testing CustomerPanel Array -- sizeCPA: 512 MyGerber.cpp: cppTestStructMyCustomerPanelArray() sizeof(myCustomerPanelArray): 4 cpID cpWidth cpHeight cpOccup stepX stepY pcbID pcbNr pcbWidth pcbHeight [0] 19 [0] 166 [0] 255 [0] 14.4 [0] 0 [0] 0 [0] 0 [0] 0 [0] 0 [0] 0 [1] 29 [1] 297 [1] 397 [1] 13.3 [1] 0 [1] 0 [1] 0 [1] 0 [1] 0 [1] 0 [2] 7 [2] 297 [2] 397 [2] 97.7 [2] 1 [2] 3 [2] 0 [2] 0 [2] 0 [2] 0 [3] 6 [3] 296 [3] 396 [3] 96.6 [3] 2 [3] 2 [3] 6 [3] 8 [3] 70 [3] 65 [4] 4 [4] 444 [4] 333 [4] 44.4 [4] 3 [4] 3 [4] 4 [4] 2 [4] 60 [4] 80 [5] 5 [5] 551 [5] 552 [5] 55.5 [5] 5 [5] 6 [5] 5 [5] 5 [5] 50 [5] 51 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [6] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 [7] 0 ~cppWrapper(): destructor: hwndGerber: 13096616 MyGerber.cpp: MyGerber_Delete(): hw: 00C7D6A8 MyGerber.cpp: ~MyGerber() dtor MyGerber.cpp: ~MyGerber(): mrbp: 00CBAB60 MyMaxRectsBinPack.cpp: ~MyMaxRectsBinPack() dtor Press any key to continue . . .