Удалите свойство Pack из объявления [DllImport], это неправильно.Вы не используете директиву #pragma pack в своем коде C, по умолчанию используется значение Pack.Если бы это было в силе, тогда ваш код на C сообщал бы 16.
Вы видите 24, потому что есть 4 байта заполнения для выравнивания двойного и 4 байта заполнения в конце структуры, чтобы сделатьдвойное выравнивание, когда структура используется в массиве.4 + 4 + 8 + 4 + 4 = 24. По умолчанию используется упаковка 8.
Вы можете повысить эффективность, поменяв значениями Value2 и Value3, чтобы получить структуру из 16 байтов, заполнение не требуется.,В случае, если это имеет значение.Вот что делает JIT-компилятор.
Следующая проблема сложнее, маршаллер P / Invoke будет маршалировать встроенный массив как SAFEARRAY.Вы можете решить эту проблему на неуправляемой стороне, используя этот код:
#include "stdafx.h"
#include <stdio.h>
#include <objidl.h>
struct PurchaseOrder
{
char* Value1;
double Value2;
LPSAFEARRAY Value3;
int fence;
};
extern "C"
__declspec(dllexport) int __stdcall MonteCarloPrint(PurchaseOrder *hostPurchaseOrders, int length)
{
printf("\nSize of PurchaseOrder: %d",sizeof(PurchaseOrder));
for (int i = 0; i < length; i++)
{
printf("\n\nAddress: %u",hostPurchaseOrders+i);
printf("\nValue1: %s",(hostPurchaseOrders+i)->Value1);
printf("\nValue2: %f",(hostPurchaseOrders+i)->Value2);
double* arrayPtr;
if (S_OK == SafeArrayAccessData((hostPurchaseOrders+i)->Value3, (void**)&arrayPtr)) {
printf("\nValue3[0]: %f", arrayPtr[0]);
printf("\nValue3[1]: %f", arrayPtr[1]);
}
}
return 0;
}
Я написал код с помощью компилятора C ++, возможно, вам придется настроить.