0

As the topic says, trying to pass a struct from c# environnement to c++.

c++ code that defines both the struct and the interface:

#pragma pack(push, 4)
    struct CEA708CONFIG 
    {
        BYTE                b608Service;            
        BYTE                bCompactStream;         
        BYTE                pActiveServices[63];    
        LONG                lActiveServiceCount;    //
        POINT               ptAlignmentPosition;    
    };
    #pragma pack(pop)


        interface
        __declspec(uuid("{some clsid}"))
        ICEA708Decoder : IUnknown {
            virtual HRESULT SetConfig(IN const CEA708CONFIG* pConfig) = 0;
            virtual HRESULT GetConfig(OUT CEA708CONFIG* pConfig) = 0;
        };

now to the c# code, i defined the same struct in c#

  [StructLayout(LayoutKind.Sequential, Pack = 4), Serializable]
    public struct CEA708CONFIG
    {
        public byte is608Service;
        public byte isCompactStream;
        //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UI1)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)]
        public IntPtr activeServices;
        public long activeServiceCount;
        public Point alignmentPosition;
    };

and the corresponding interface that accepts the config structure

[ComVisible(true), ComImport, Guid("same clsid as above"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICEA708Decoder
{
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int SetConfig([In, MarshalAs(UnmanagedType.Struct)] ref CEA708CONFIG config);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetConfig([Out, MarshalAs(UnmanagedType.Struct)] out CEA708CONFIG config);
    }

my problem occurs whenever i try to pass the structure, i can clearly see that while executing the c# code the entire struct is intialized with "reasonable" values, but once passed to the c++, i see that something has happened during the transaction.

the c# code that makes the magic happen:

            CEA708CONFIG   cc708Config;
            ICEA708Decoder CC708DecoderConfig = CC708Filter as ICEA708Decoder;

            if (CC708DecoderConfig == null)
            {
                throw new ApplicationException("Couldn't get ICEA708Decoder structure");
            }

            byte[] dataByte = new byte[63];
            int    size     = Marshal.SizeOf(dataByte[0]) * dataByte.Length;
            IntPtr pnt      = Marshal.AllocHGlobal(size);

            dataByte[0] = 1;
            Marshal.Copy(dataByte, 0, pnt, dataByte.Length);
            cc708Config.activeServices = pnt;
            if (0 != (hr = CC708DecoderConfig.SetConfig(ref cc708Config)))
            {
                throw new ApplicationException("Couldn't SetConfig() because: " + DirectShowLib.DsError.GetErrorText(hr));
            }

and the exception triggered by the SetConfig is:

{"Cannot marshal field 'activeServices' of type 'CCReIndexer.Graphs.CEA708CONFIG': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or SysUInt).":""}

thanks for your help!!

4
  • The error tells you what the problem is. Commented Aug 6, 2012 at 12:52
  • That field must be byte[]. And MarshalAs(UnmanagedType.Struct) is wrong, delete it. Commented Aug 6, 2012 at 12:54
  • when i change it back to byte[] im not able to compile the example above as there are typs mismatch conversions Commented Aug 6, 2012 at 12:59
  • i managed to convert the array to be a fixed size array, but this still produces me a garbage object. Commented Aug 6, 2012 at 13:48

1 Answer 1

2

Have you tried transfer array as array?

[StructLayout(LayoutKind.Sequential, Pack = 4), Serializable]
public struct CEA708CONFIG
{
    public byte is608Service;
    public byte isCompactStream;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)]
    public byte[] activeServices;
    public long activeServiceCount;
    public Point alignmentPosition;
};

byte[] dataByte = new byte[63];
cc708Config.activeServices = dataByte;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.