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 . . .