将参数从c#传递到c++; 正如主题所说的,试图把一个C语言环境中的结构传递给C++。

将参数从c#传递到c++; 正如主题所说的,试图把一个C语言环境中的结构传递给C++。,c#,c++,.net,com-interop,C#,C++,.net,Com Interop,定义结构和接口的c++代码: #pragma pack(push, 4) struct CEA708CONFIG { BYTE b608Service; BYTE bCompactStream; BYTE pActiveServices[63]; LONG

定义结构和接口的c++代码:

#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;
        };
现在来看c代码,我在c中定义了相同的结构#

以及接受配置结构的相应接口

[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);
    }
当我尝试通过这个结构时,我的问题就出现了,我可以清楚地看到,在执行C代码时,整个结构都被“合理”的值所初始化,但是一旦传递给C++,我就看到事务中发生了什么。 让奇迹发生的c代码:

            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));
            }
SetConfig触发的异常为:

{“无法封送类型为的字段'activeServices' “CCReIndexer.Graphs.CEA708CONFIG”:托管/非托管类型无效 组合(Int/UInt必须与SysInt或SysUInt配对)。“:”“}


谢谢你的帮助

您是否尝试将数组转换为数组

[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;

错误告诉您问题所在。该字段必须为字节[]。如果Marshallas(UnmanagedType.Struct)错误,请将其删除。当我将其更改回byte[]时,我无法编译上面的示例,因为存在类型不匹配的转换。我已设法将数组转换为固定大小的数组,但这仍然会生成一个垃圾对象。
[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;