c# - 将参数从 C# 传递到 C++

标签 c# c++ .net com-interop

如主题所述,尝试将结构从 C# 环境传递到 C++。

同时定义结构和接口(interface)的 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# 中定义了相同的结构

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

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

[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 触发的异常是:

{"Cannot marshal field 'activeServices' of type 'CCReIndexer.Graphs.CEA708CONFIG': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or 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;

关于c# - 将参数从 C# 传递到 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11827830/

相关文章:

c# - 无法通过 Microsoft.Graph 访问已删除项目

c# - ActionFilterAttribute 未调用

c# - 将字符串转换为 smalldatetime

c# - TDD:你会如何在这门课上工作,测试先行的风格?

c# - 嵌套函数调用 - 最佳实践是什么?

c++ - 如何在 OpenCV 中访问单 channel 矩阵

C++ 单例 GetInstance() 返回

c++ - 使用 std::move,调用 move 构造函数但对象仍然有效

.net - 如果未安装 .NET 3.5,如何避免 FileNotFoundException?

c# - 包含来自类库的配置文件