Question

I need to get Data from a C DLL to a C# Application. Here is the error :

Cannot marshal field 'Counters' of type 'KnittingWago.Common.WAGO_DATA_TO_USER_T': Invalid managed/unmanaged type combination (Array fields must be paired with ByValArray or SafeArray).

Here is the DLL .h

#define WAGO_NB_COUNTERS_C 80
#define WAGO_NB_ENCODERS_C 10 

struct WAGO_DATA_TO_USER_T
{
   unsigned int Counters[WAGO_NB_COUNTERS_C];
   int Encoders[WAGO_NB_ENCODERS_C];
   unsigned int Weight;
   bool CalibrationValid;
   bool LastCalibrationFailed;
};

Here is the C# Struct declaration :

const int WAGO_NB_COUNTERS_C = 80;
const int WAGO_NB_ENCODERS_C = 10;

struct WAGO_DATA_TO_USER_T
{
   [MarshalAs(UnmanagedType.U4, SizeConst = GlobalConstant.WAGO_NB_COUNTERS_C)]
   UInt32[] Counters;
   [MarshalAs(UnmanagedType.I4, SizeConst = GlobalConstant.WAGO_NB_ENCODERS_C)]
   Int32[] Encoders;
   UInt32 Weight;
   Boolean CalibrationValid;
   Boolean LastCalibrationFailed;
};

How do I declare the C# struct to get the rigth data without error ?

Thanks


EDIT :

I've rewrite the Struct as :

internal struct WAGO_DATA_TO_USER_T
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = GlobalConstant.WAGO_NB_COUNTERS_C)]
    UInt32[] Counters;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = GlobalConstant.WAGO_NB_ENCODERS_C)]
    Int32[] Encoders;
    UInt32 Weight;
    Boolean CalibrationValid;
    Boolean LastCalibrationFailed;
};

No more Error, but the Values are not as expected.

Should be like :

Counter[0] = ~ 5000
Counter[1] = ~ 30000
Counter[2-79] = 0

Really are :

Counter[0] = 40
Counter[1] = 1080228
Counter[2] = 82964616
Counter[3-79] = All have a non-zero value
Was it helpful?

Solution

The Marshalling was correct but the Device I was calling was not initialized by the external unmanaged dll. So I was reading uninitialisez memory that lead to that unvalid data

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top