Click here to Skip to main content
15,896,606 members
Home / Discussions / C#
   

C#

 
AnswerRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn30-Jun-07 5:10
sitebuilderLuc Pattyn30-Jun-07 5:10 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
TomWolfstein30-Jun-07 6:05
TomWolfstein30-Jun-07 6:05 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn30-Jun-07 6:57
sitebuilderLuc Pattyn30-Jun-07 6:57 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
TomWolfstein30-Jun-07 8:51
TomWolfstein30-Jun-07 8:51 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn30-Jun-07 14:27
sitebuilderLuc Pattyn30-Jun-07 14:27 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
TomWolfstein1-Jul-07 7:16
TomWolfstein1-Jul-07 7:16 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn1-Jul-07 8:34
sitebuilderLuc Pattyn1-Jul-07 8:34 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
TomWolfstein4-Jul-07 21:57
TomWolfstein4-Jul-07 21:57 
Hi.
Sorry it took me so long to answer. It's exam period..

I'll start with the end. I completley agree that it's best to learn P/Invoke and the principles of marshaling unmanaged code to managed code, and that simple examples should come before diving into a project like this.
I wish I knew all this 3 month ago when I started this. I didn't, and didn't have much choice as I am not writing this for my pleasure but as a final project for my degree. I am as unhappy with this as much as you can imagine. I want to thank you again for taking the time to explain all of this to a newbie like me.
Besides, don't they always say the best way to learn to swim is to just dive in Smile | :)

Now back to the fun (?).
1. I understand the structure I created to replace the union is not a good idea. I tried it as a way of getting the structure containing to occupy the same size it would have, had I used a union.
Now that I think the problem is somewhere else I can probably (hopefuly) change it back.

2. You are probably right here again. When I tried to offset the union 8 bytes, the alignment error disappeared and was replaced by the error caused by trying to marshal an array of structs.
Maybe this is because some of these structs have marshaled arrays in them.

4. Trust me, you are not the only obe confused by these structs, but as I said at the begining, the C source code is not mine. It is an open source implementation of the VC1 video standart. I'll be happy to send it to you if you are interested.
Meanwhile, I'll try to be clearer. I imported all of structs from the C code to C#, and marshalled all of them.
Basicaly there are two structures who contain in them, by way of value, reference and other, all of the other structures in the code.
I am sending an IntPtr from the C# code to the VC1 decoder (C code), and return that IntPtr with the address of the structure I want to access (I do it with 'out' rather than actually returning it, but the result is the same).
Right now some of the fields in the super struct (int C#) are garbage, and some are perfectly accessible. I think (and please correct me if I am wrong. there is a good chance I am), that this is because I did not import and marshall ALL of the structs, and this is causing an alignment error in the C# super struct, making it not the same size as the C code struct.

I have this struct 'vc1_sMB':
/** Description: A structure to hold macroblock data.*/<br />
        [StructLayout(LayoutKind.Sequential)]<br />
<br />
        public unsafe struct vc1_sMB<br />
        {<br />
            vc1_eMBType eMBType;            /** Macroblock type */<br />
            vc1_eACPred eACPred;            /** AC prediction status */<br />
            vc1_eBlkType eBlkType;           /** One of 8x8,8x4,4x8,4x4, or Any<br />
                                                    (Any=block based choice) */<br />
            byte OverlapFilter;      /** Overlap filter active for this macroblock */<br />
            byte Skipped;            /** Indicated macroblock is motion predicted only */<br />
            byte CBPCY;              /** Coded  block pattern, where:<br />
                                                  *  - bit 5 set means Y0 is coded<br />
                                                  *  - bit 4 set means Y1 is coded<br />
                                                  *  - bit 3 set means Y2 is coded<br />
                                                  *  - bit 2 set means Y3 is coded<br />
                                                  *  - bit 1 set means Cb is coded<br />
                                                  *  - bit 0 set means Cr is coded<br />
                                                  */<br />
            byte MVBP;               /** Motion vector block pattern, with:<br />
                                                  *  - bit3 set if dmv!=0 for Y0<br />
                                                  *  - bit2 set if dmv!=0 for Y1<br />
                                                  *  - bit1 set if dmv!=0 for Y2<br />
                                                  *  - bit0 set if dmv!=0 for Y3<br />
                                                  */<br />
            vc1_sQuant sQuant;             /** Macroblock Quantizer information */<br />
            <br />
            /***vc1_sBlk sBlk[VC1_BLOCKS_PER_MB];    /** Block level information */<br />
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public vc1_sBlk[] sBlk; <br />
            /** Block level information */<br />
            <br />
        };


As you can see in the last line, there is a marshaled array of 'vc1_sBlk' structs.
The C version of this struct is exactly the same apart ftom the marshaled array, and I left the arrays original definition commented.

'vc1_sBlk' looks like this (now marshaled like you said to implement the union):
/** Description: Structure defining the state required for a block.*/<br />
        [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Ansi)]<br />
        public unsafe struct vc1_sBlk<br />
            {<br />
               [FieldOffset(0), MarshalAs(UnmanagedType.I4)] public vc1_eBlkType eBlkType;<br />
               /** Block type */<br />
               <br />
               [FieldOffset(4), MarshalAs(UnmanagedType.U1)] public byte Coded; <br />
               /** Non zero AC coefficients for Intra, non zero AC/DC for Inter */<br />
<br />
               [FieldOffset(8)] public vc1_sBlkIntra sIntra; /** Intra block state information */<br />
               [FieldOffset(8)] public vc1_sBlkIntra sInter; /** Inter block state information */<br />
            };


While it's original definition in the C code is this (FLAG is a 1B short):
typedef struct<br />
{<br />
    vc1_eBlkType        eBlkType;       /** Block type */<br />
    FLAG                Coded;          /** Non zero AC coefficients for Intra,<br />
                                            non zero AC/DC for Inter */<br />
    union<br />
    {<br />
        vc1_sBlkIntra   sIntra;         /** Intra block state information */<br />
        vc1_sBlkInter   sInter;         /** Inter block state information */<br />
    }                   u;              /** Intra/Inter union */<br />
} vc1_sBlk;


And as you've seen before 'vc1_sBlkIntra' looks like this in c#(the C code is in comments):
/** Description: Structure defining the state required for intra blocks.*/<br />
      [StructLayout(LayoutKind.Sequential)]<br />
      public unsafe struct vc1_sBlkIntra<br />
          {<br />
              ushort NZC;            /** NUMZERO and NUMCOEF (excludes DC) */ <br />
              /**** ushort was originally 'vc1_NumZeroCoef' which is a typedef in the decoder***/<br />
              short DC;             /** Quantized DC for prediction */<br />
              /***short ACTop[7];       /** Quantized AC top row for prediction */<br />
              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public short[] ACTop; <br />
              /** Quantized AC top row for prediction */<br />
              /***short ACLeft[7];      /** Quantized AC left column for prediction */<br />
              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public short[] ACLeft; <br />
              /** Quantized AC left column for prediction */<br />
              /***short moothRows[16]; /** Bottom two rows kept for overlap smoothing */<br />
              [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public short[] moothRows;<br />
              /** Bottom two rows kept for overlap smoothing */<br />
          };


And 'vc1_sBlkInter' looks like this:
/** Description: Structure defining the state required for inter blocks.*/<br />
      [StructLayout(LayoutKind.Sequential)]<br />
      public unsafe struct vc1_sBlkInter<br />
      {<br />
          /***vc1_NumZeroCoef NZC[4]; /** NUMZERO and NUMCOEF for sub-blocks (includes DC) */ <br />
          /**** ushort was originally 'vc1_NumZeroCoef' which is a typedef in the decoder***/<br />
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public ushort[] NZC; <br />
          /** NUMZERO and NUMCOEF for sub-blocks (includes DC) */<br />
          <br />
          /***vc1_sMotion sMotion[2];     /** Forward and Backward motion parameters */<br />
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public vc1_sMotion[]  sMotion;<br />
          /** Forward and Backward motion parameters */<br />
      } ;

I will not bother you with all the definitions of the other structures (everything that starts with an s, since there is nothing interesting there but normal type variables).

So 'vc1_sBlk' has in it structures that contain marshaled arrays (which like you said are references, if it matters).

All of this compiles without problem, but after I changed the offset to what you suggested, the error I got is this:
Cannot marshal field 'sPosition' of type 'vc1DEC_sState': The type definition of this field has layout information but has an invalid managed/unmanaged type combination or is unmarshalable.

(I apologize. This really is never ending)

'vc1DEC_sState' is this (only the first line is important, but I pasted all of it):
  /** Description:Structure containing the state of the decoder.**/<br />
        [StructLayout(LayoutKind.Sequential)]<br />
        public unsafe struct vc1DEC_sState<br />
        {<br />
            public vc1_sPosition sPosition;     /** Macroblock position structure */<br />
            vc1_sPicture pPicture;              /** Picture information */<br />
<br />
            public int FrameNum;               /** Current frame number */<br />
<br />
            /* Pointer to other data structures */<br />
            vc1_sMB pMB;                   /** Pointer to macroblock data */<br />
            <br />
            /* Limits */<br />
<br />
            int NumFields;              /** Number of fields per frame */<br />
            int MaxMBs;                 /** Maximum number of macroblocks */<br />
            vc1_sLevelLimit pLevelLimit;           /** Limits for current level and profile */<br />
<br />
            /* Configuration */<br />
            vc1_sSequenceLayer sSeqParams;             /** Data from the sequence layer */<br />
            vc1DEC_sPictureLayerParams sPicParams;          /** Data from the current picture layer */<br />
<br />
            byte NotFirstMode3InFrame;   /** 1 if not first mode 3 escape in frame */<br />
            /* (8.1.1.10 AC coef decoder) */<br />
            byte LevelCodeSize;          /** Level code size for mode 3 escape,<br />
                                                                per frame */<br />
            byte RunCodeSize;            /** Run code size for mode 3 escape, <br />
                                                                per frame */<br />
<br />
            byte ZigZagTableIndex;       /** Index to select zigzag table */<br />
            byte FirstFrameInStream;     /** Non-zero if this is the first frame */<br />
            byte BitplaneCodingUsed;     /** Non-zero if bitplane coding is in use */<br />
<br />
            byte FirstCodedBlock;        /** First coded block in current macroblock */<br />
<br />
            public vc1_sReferencePicture pCurrentRef;     <br />
            /** Pointer to the current reference picture into which blocks are decoded */<br />
<br />
            vc1_sMotionHist pMVHistBuffer;         /** Pointer to the motion vector history buffer */<br />
            uint FieldCount;             /** Number of fields present in the current picture */<br />
<br />
        }


And inside it, the 'sPosition' mentioned is this (again just notice that vc1_sMB is defined here):
  /** Description:<br />
         * Current position structure describing the macroblock being<br />
         * processed and the slice, field, and picture it lies in.<br />
         */<br />
        [StructLayout(LayoutKind.Sequential)]<br />
        public unsafe struct vc1_sPosition<br />
        {<br />
            vc1_ePictureType ePictureType;   /** Picture type: I, P, B or BI */<br />
            vc1_ePictureFormat ePictureFormat; /** Picture format: Progressive, Interlace Field/frame */<br />
            vc1_eProfile eProfile;       /** Profile Simple/Main/Advanced */<br />
            vc1_eMVMode eMVMode;        /** Motion vector mode for this picture */<br />
            vc1_eMVRange eMVRange;       /** Motion vector range setting for this picture */<br />
            byte BottomField;    /** 0=Top Field, 1=Bottom Field */<br />
            byte SecondField;    /** 0=First Field, 1=Second Field */<br />
            vc1_sMB pCurMB;        /** Pointer to the current macroblock */<br />
            vc1_sMB pStartMB;      /** Pointer to start of macroblock circular buffer */<br />
            vc1_sMotionHist pMVHist;       /** Current position in motion vector history buffer */<br />
            uint SizeMB;         /** Circular buffer size in macroblocks */<br />
            ushort X;              /** X macroblock offset in current slice */<br />
            ushort Y;              /** Y macroblock offset in current slice */<br />
            ushort SliceY;         /** Y macroblock offset of slice in picture */<br />
            ushort WidthMB;        /** Width in macroblocks of coded picture */<br />
            ushort HeightMB;       /** Height in macroblocks of coded picture */<br />
            public uint CodedWidth;     /** Width in pixels of coded picture */<br />
            public uint CodedHeight;    /** Height in pixels of coded picture */<br />
            uint MaxCodedWidth;  /** Max Width in pixels of coded picture */<br />
            uint MaxCodedHeight; /** Max Height in pixels of coded picture */<br />
            byte PQuant;         /** Picture quantizer */<br />
            byte BFraction;      /** BFRACTION syntax element */<br />
            byte NumRef;         /** Number of reference fields-1 */<br />
            byte RefField;       /** Reference field when NumRef==0 */<br />
            byte IntraBias;      /** Bias to add to intra blocks post transform */<br />
            byte RangeYScale;    /** Y scaling factor times 8 */<br />
            byte RangeUVScale;   /** UV scaling factor times 8 */<br />
            byte FastUVMC;       /** Fast U,V motion compensation byte */<br />
            vc1_ePictureRes ePictureRes;    /** Picture resolution scale mode */<br />
            vc1_sReferencePicture pReferenceOld;  /** Pointer to old I/P reference picture */<br />
            vc1_sReferencePicture pReferenceNew;  /** Pointer to new/current I/P */<br />
            vc1_sReferencePicture pReferenceB;    /** Reconstructed B picture */<br />
            vc1_sReferencePicture pReferenceNoIC; <br />
            /** Backup copy of reference before intensity compensation applied */<br />
<br />
            /***vc1_sScaleMV pScaleMV[2];        /** MV scaling (forward, backward) */<br />
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]<br />
            public vc1_sScaleMV[] pScaleMV;        /** MV scaling (forward, backward) */<br />
            /***short pSmooth[6][64]; /** Overlap smoothing macroblock history (left) */<br />
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6*64)] public short[] pSmooth;<br />
        } ;


All of this brings us back to the begining (did I apologize already for the length of this?)
If you remember in the begining of this post, 1e100000000000 lines above, I said that the last line of 'vc1_sMB' is the declaration of a marshaled array of 'vc1_sBlk'.
If instead of this array I declare this:
public vc1_sBlk sBlk; /** Block level information */ Then there is no error.
I can't get access to all of the fields in all of the structs, but at least there is no error.

So, finally, I suspect this array.
Am I right to suspect it?
Am I on the right way to gain normal access to the structs fields?
Would it help if I sent you the C code?

I did not intend for this to be the longest post ever. I am deeply thankful for the time you are putting into just reading all of this, not to mention trying to understand and come up with solutions.

Thanks.
Tom.
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn5-Jul-07 0:17
sitebuilderLuc Pattyn5-Jul-07 0:17 
GeneralRe: Help with TypeLoadException (marshaling unmanaged code) Pin
Luc Pattyn1-Jul-07 9:14
sitebuilderLuc Pattyn1-Jul-07 9:14 
Questionvalidating a formula Pin
Bojja Lakshmi30-Jun-07 2:50
Bojja Lakshmi30-Jun-07 2:50 
AnswerRe: validating a formula Pin
User 665830-Jun-07 3:32
User 665830-Jun-07 3:32 
QuestionDataGrid with checkbox Pin
-spy-30-Jun-07 2:40
-spy-30-Jun-07 2:40 
AnswerRe: DataGrid with checkbox Pin
DanB198330-Jun-07 8:24
DanB198330-Jun-07 8:24 
QuestionInvalid Argument exception? Pin
$uresh $hanmugam30-Jun-07 1:58
$uresh $hanmugam30-Jun-07 1:58 
AnswerRe: Invalid Argument exception? [modified] Pin
Luc Pattyn30-Jun-07 3:07
sitebuilderLuc Pattyn30-Jun-07 3:07 
Questionreading file error Pin
tauras8130-Jun-07 1:41
tauras8130-Jun-07 1:41 
AnswerRe: reading file error Pin
Luc Pattyn30-Jun-07 1:58
sitebuilderLuc Pattyn30-Jun-07 1:58 
Questionarray of type label Pin
Glen Harvy29-Jun-07 23:47
Glen Harvy29-Jun-07 23:47 
AnswerRe: array of type label Pin
Sathesh Sakthivel29-Jun-07 23:53
Sathesh Sakthivel29-Jun-07 23:53 
GeneralRe: array of type label Pin
Glen Harvy30-Jun-07 0:09
Glen Harvy30-Jun-07 0:09 
AnswerRe: array of type label Pin
Luc Pattyn29-Jun-07 23:57
sitebuilderLuc Pattyn29-Jun-07 23:57 
GeneralRe: array of type label Pin
Glen Harvy30-Jun-07 0:11
Glen Harvy30-Jun-07 0:11 
GeneralRe: no Replace !! Pin
Luc Pattyn30-Jun-07 1:14
sitebuilderLuc Pattyn30-Jun-07 1:14 
AnswerRe: array of type label Pin
Guffa30-Jun-07 0:08
Guffa30-Jun-07 0:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.