I am trying to write a wrapper for the standard VC1 decoder, and I need to resolve a "TypeLoadException"
The decoder comes an an executable which I've turned into a .dll. This decoder has about a ton of structures, most of the containing other structures, arrays of structures, and unions of structures.
I need help converting the following to managed code:
The unmanaged structure is this:
typedef struct
{
vc1_eBlkType eBlkType; /** Block type */
FLAG Coded; /** Non zero AC coefficients for Intra,
non zero AC/DC for Inter */
union
{
vc1_sBlkIntra sIntra; /** Intra block state information */
vc1_sBlkInter sInter; /** Inter block state information */
} u; /** Intra/Inter union */
} vc1_sBlk;As you can see it contains an enumerator and a union of another type of struct.
I've taken the unmanaged vc1_sBlkInter structure
typedef struct
{
vc1_NumZeroCoef NZC; /** NUMZERO and NUMCOEF (excludes DC) */
HWD16 DC; /** Quantized DC for prediction */
HWD16 ACTop[7]; /** Quantized AC top row for prediction */
HWD16 ACLeft[7]; /** Quantized AC left column for prediction */
HWD16 SmoothRows[16]; /** Bottom two rows kept for overlap smoothing */
} vc1_sBlkIntra;And turned it into a managed structure :
[StructLayout(LayoutKind.Sequential)]
public unsafe struct vc1_sBlkIntra
{
ushort NZC; /** NUMZERO and NUMCOEF (excludes DC) */
short DC; /** Quantized DC for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public short[] ACTop; /** Quantized AC top row for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public short[] ACLeft; /** Quantized AC left column for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public short[] moothRows; /** Bottom two rows kept for overlap smoothing */
};Now, I am trying to turn vc1_sBlk into a managed structure as well.
The last attempt is this
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct vc1_sBlk
{
[FieldOffset(0), MarshalAs(UnmanagedType.I4)]
public vc1_eBlkType eBlkType; /** Block type */
[FieldOffset(4), MarshalAs(UnmanagedType.AsAny)]
public byte Coded; /** Non zero AC coefficients for Intra, non zero AC/DC for Inter */
[FieldOffset(5), MarshalAs(UnmanagedType.Struct, SizeConst = 64)] public vc1_sBlkIntra sIntra; /** Intra block state information */
[FieldOffset(5), MarshalAs(UnmanagedType.Struct, SizeConst = 64)] public vc1_sBlkIntra sInter; /** Inter block state information */
} ;But I have pretty much tried every kind of marshalling mentioned online, but I keep getting this error:
"Could not load type 'vc1_sBlk'...because it contains an object field at offset 5 that is incorrectly aligned or overlapped by a non-object field."
I am really stuck here and I can't find an answer to this anywhere.
ANY help would be greatly appreciated.
Tom
AlanPosted Jul 2, 2007, 4:44 PM
I thought I'd go back to first principles, Tom, to see what I'd come up with from the Win32 definitions alone, the answer being as follows (not necessarily correct, of course :))
[StructLayout(LayoutKind.Sequential)]
struct vc1_sBlk
{
public vc1_eBlkType eBlkType; /** Block type */
public short Coded; /** Non zero AC coefficients for Intra,
non zero AC/DC for Inter */
public IntraInterUnion u;
}
[StructLayout(LayoutKind.Explicit)]
struct IntraInterUnion
{
[FieldOffset(0)]public vc1_sBlkIntra sIntra; /** Intra block state information */
[FieldOffset(0)]public vc1_sBlkInter sInter; /** Inter block state information */
}
[StructLayout(LayoutKind.Sequential)]
struct vc1_sBlkIntra
{
public ushort NZC; /** NUMZERO and NUMCOEF (excludes DC) */
public short DC; /** Quantized DC for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public short[] ACTop; /** Quantized AC top row for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public short[] ACLeft; /** Quantized AC left column for prediction */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public short[] SmoothRows; /** Bottom two rows kept for overlap smoothing */
}
As far as explicit layout is concerned, the rule is that you can have both value types and reference types in the same struct as long as they don't overlap. However, I don't think you have any reference types here - just structs - so that's not a problem in the union definition.
Also, AFAIK, there is no need to align members of the struct in any particular way when you are using explicit layout. In effect you're creating a struct with a packing size of 1.
However, I don't think there's any need to use explicit layout for the vc1_sBlk struct, even though it contains a union. You can just use sequential layout with the default packing size.
Finally, there is no need to use the 'unsafe' keyword unless you are explicitly using pointers in your struct definitions which doesn't appear to be the case.
Tom WolfsteinPosted Jul 1, 2007, 1:32 PM
I wrote a detailed reply about wht I found, but It was deleted.
Could you read what I wrote here:
http://www.codeproject.com/script/comments/forums.asp?forumid=1649&select=2107863&df=100&fr=49.5&msg=2107863
And tell me if you have any ideas on how to solve this?
Thanks :-)
Tom
AlanPosted Jun 30, 2007, 4:20 PM
See if it makes any difference if you change:
[FieldOffset(4), MarshalAs(UnmanagedType.AsAny)]
public byte Coded; /** Non zero AC coefficients for Intra, non zero AC/DC for Inter */
to this:
[FieldOffset(4), MarshalAs(UnmanagedType.U1)]
public byte Coded; /** Non zero AC coefficients for Intra, non zero AC/DC for Inter */