Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Marshalling a complex structure to C#

360 views
Skip to first unread message

ctorob

unread,
Jun 29, 2003, 8:45:11 AM6/29/03
to
I have been trying for hours to marshal the following complex C structure
into C# with no luck.

(Sorry for the long posting)

/*
typedef struct _HIDP_VALUE_CAPS {
USAGE UsagePage;
UCHAR ReportID;
BOOLEAN IsAlias;
USHORT BitField;
USHORT LinkCollection;
USAGE LinkUsage;
USAGE LinkUsagePage;
BOOLEAN IsRange;
BOOLEAN IsStringRange;
BOOLEAN IsDesignatorRange;
BOOLEAN IsAbsolute;
BOOLEAN HasNull;
UCHAR Reserved;
USHORT BitSize;
USHORT ReportCount;
USHORT Reserved2[5];
ULONG UnitsExp;
ULONG Units;
LONG LogicalMin, LogicalMax;
LONG PhysicalMin, PhysicalMax;
union {
struct {
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct {
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
USHORT DataIndex, Reserved4;
} NotRange;
};
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;

*/

This is the Marshaling format I am using. I have tried a number
of "variations on the theme" with similar fate.

// Structures in the Union
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Range
{
public System.UInt16 UsageMin; // USAGE UsageMin;
public System.UInt16 UsageMax; // USAGE UsageMax; ;
public System.UInt16 StringMin; // USHORT StringMin;
public System.UInt16 StringMax; // USHORT StringMax;
public System.UInt16 DesignatorMin; // USHORT DesignatorMin;
public System.UInt16 DesignatorMax; // USHORT DesignatorMax;
public System.UInt16 DataIndexMin; // USHORT DataIndexMin;
public System.UInt16 DataIndexMax; // USHORT DataIndexMax;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct NotRange
{
public System.UInt16 Usage;
public System.UInt16 Reserved1;
public System.UInt16 StringIndex;
public System.UInt16 Reserved2;
public System.UInt16 DesignatorIndex;
public System.UInt16 Reserved3;
public System.UInt16 DataIndex;
public System.UInt16 Reserved4;
}

//

// The main structure in an explicit mapping
[StructLayout(LayoutKind.Explicit, CharSet= CharSet.Ansi)]
public unsafe struct HIDP_VALUE_CAPS
{
//
[FieldOffset(0)] public System.UInt16 UsagePage; // USHORT
[FieldOffset(2)] public System.Char ReportID; // UCHAR ReportID;
[FieldOffset(3)] public System.Boolean IsAlias; // BOOLEAN IsAlias;
[FieldOffset(4)] public System.UInt16 BitField; // USHORT BitField;
[FieldOffset(6)] public System.UInt16 LinkCollection; //USHORT
LinkCollection;
[FieldOffset(8)] public System.UInt16 LinkUsage; // USAGE LinkUsage;
[FieldOffset(10)] public System.UInt16 LinkUsagePage; // USAGE
LinkUsagePage;
[FieldOffset(12)] public System.Boolean IsRange; // BOOLEAN IsRange;
[FieldOffset(13)] public System.Boolean IsStringRange; // BOOLEAN
IsStringRange;
[FieldOffset(14)] public System.Boolean IsDesignatorRange; // BOOLEAN
IsDesignatorRange;
[FieldOffset(15)] public System.Boolean IsAbsolute; // BOOLEAN IsAbsolute;
[FieldOffset(16)] public System.Boolean HasNull; // BOOLEAN HasNull;
[FieldOffset(17)] public System.Char Reserved; // UCHAR Reserved;
[FieldOffset(18)] public System.UInt16 BitSize; // USHORT BitSize;
[FieldOffset(20)] public System.UInt16 ReportCount; // USHORT ReportCount;
// Flattened Array Reserved2
[FieldOffset(22)] public System.UInt16 Reserved2a; // USHORT Reserved2[0];
[FieldOffset(24)] public System.UInt16 Reserved2b; // USHORT Reserved2[1];
[FieldOffset(26)] public System.UInt16 Reserved2c; // USHORT Reserved2[2];
[FieldOffset(28)] public System.UInt16 Reserved2d; // USHORT Reserved2[3];
[FieldOffset(30)] public System.UInt16 Reserved2e; // USHORT Reserved2[4];
// end of flatten array
[FieldOffset(32)] public System.UInt16 UnitsExp; // ULONG UnitsExp;
[FieldOffset(34)] public System.UInt16 Units; // ULONG Units;
[FieldOffset(36)] public System.Int16 LogicalMin; // LONG LogicalMin; ;
[FieldOffset(38)] public System.Int16 LogicalMax; // LONG LogicalMax
[FieldOffset(40)] public System.Int16 PhysicalMin; // LONG PhysicalMin,
[FieldOffset(42)] public System.Int16 PhysicalMax; // LONG PhysicalMax;
// The Structs in the Union
[FieldOffset(44)] public Range Range;
[FieldOffset(44)] public Range NotRange;
}

The C++ format function (part of the HID.dll)

NTSTATUS
HidP_GetValueCaps(
IN HIDP_REPORT_TYPE ReportType,
OUT PHIDP_VALUE_CAPS ValueCaps,
IN OUT PULONG ValueCapsLength,
IN PHIDP_PREPARSED_DATA PreparsedData
);


for which my "unsafe C#" call and wrapper are as follows:

// the call
[DllImport("hid.dll", SetLastError=true)]
private unsafe static extern int HidP_GetValueCaps(
HIDP_REPORT_TYPE ReportType, // IN HIDP_REPORT_TYPE ReportType,
ref HIDP_VALUE_CAPS[] ValueCaps, // OUT PHIDP_VALUE_CAPS ValueCaps,
ref int ValueCapsLength, // IN OUT PULONG ValueCapsLength,
int pPHIDP_PREPARSED_DATA); // IN PHIDP_PREPARSED_DATA PreparsedData

// the wrapper
public int CT_HidP_GetValueCaps(ref int CapsLength, int
pPHIDP_PREPARSED_DATA)
{
HIDP_REPORT_TYPE myType =0; // Indicates an input report
myHIDP_VALUE_CAPS = new HIDP_VALUE_CAPS[5];
return HidP_GetValueCaps(
myType,
ref myHIDP_VALUE_CAPS,
ref CapsLength,
pPHIDP_PREPARSED_DATA);
}

(Note : ** My pPHIDP_PREPARSED_DATA is correct and not the source of the
problem)

I keep on getting the An unhandled exception of type
'System.ExecutionEngineException'.
Any suggestions would be greatly appreciated.

Camilo Toro
cto...@worldnet.att.net


Mattias Sjögren

unread,
Jun 30, 2003, 6:44:40 AM6/30/03
to

>// The main structure in an explicit mapping
>[StructLayout(LayoutKind.Explicit, CharSet= CharSet.Ansi)]
>public unsafe struct HIDP_VALUE_CAPS
>{
>//
>[FieldOffset(0)] public System.UInt16 UsagePage; // USHORT
>[FieldOffset(2)] public System.Char ReportID; // UCHAR ReportID;
>[FieldOffset(3)] public System.Boolean IsAlias; // BOOLEAN IsAlias;

I'd mark all bools in the struct with

[MarshalAs(UnmanagedType.I1)]


>for which my "unsafe C#" call and wrapper are as follows:
>
>// the call
>[DllImport("hid.dll", SetLastError=true)]
>private unsafe static extern int HidP_GetValueCaps(
> HIDP_REPORT_TYPE ReportType, // IN HIDP_REPORT_TYPE ReportType,
> ref HIDP_VALUE_CAPS[] ValueCaps, // OUT PHIDP_VALUE_CAPS ValueCaps,
> ref int ValueCapsLength, // IN OUT PULONG ValueCapsLength,
> int pPHIDP_PREPARSED_DATA); // IN PHIDP_PREPARSED_DATA PreparsedData

Try it like this

[DllImport("hid.dll", SetLastError=true)]
private static extern int HidP_GetValueCaps(
HIDP_REPORT_TYPE ReportType,
[In, Out] HIDP_VALUE_CAPS[] ValueCaps,
ref int ValueCapsLength,
int pPHIDP_PREPARSED_DATA);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

ctorob

unread,
Jun 30, 2003, 7:20:53 AM6/30/03
to
Many Thanks!!!!
Your suggestions works.

Camilo Toro


0 new messages