使用c#和c ++之间的字符串封装结构数组。 字符串是空的

我在C#和C ++之间编排这个结构最困难。 什么使得排除故障非常困难是有些时候字符串被数据填充(wtf),但大多数情况下它们不是。

我试着发送一个结构数组以及一个IntPtr,但结果是相似的,结构中的字符串几乎总是空的,我无法弄清楚我在编组中的错误。 该代码发布如下。 任何帮助,将不胜感激。

编辑***发现问题出在C ++端,所有编组的东西都是正确的。 感谢提示汉斯。 ***

C ++:

#pragma pack (push, 1)
typedef struct
{
    char FirmwareVers[FS_MAX_FIRMWARE_VER];
    char SerialNum[FS_MAX_SERIAL_NUM];
    char HardwareVers[FS_MAX_HW_VER];
    ULONG StatusFlags;
    int LMIndex; 
} FS_LMON_STATUS, *PFS_LMON_STATUS;


DllExport int _stdcall FS_GetLMs(PFS_LMON_STATUS pLaunchMonInfo, int MaxLaunchMons, int *pNumLaunchMons)
{
  int Cnt;
  FS_LMON_STATUS LMStatus;

    if(!g_IsInitalized)
        return FS_NOT_INITALIZED;

    *pNumLaunchMons = 0;

    if(MaxLaunchMons == 0)
        return FS_ERROR;

    for(Cnt = 0; Cnt < MAX_LM_CONNECTIONS; Cnt++)
    {
        if(g_CreatedClasses.pLMList->GetLMStatus(Cnt, &LMStatus) != FS_SUCCESS)
            continue;

        if(LMStatus.LMIndex != INVALID_LM_INDEX)
        {
            memcpy(pLaunchMonInfo, &LMStatus, sizeof(LMStatus));
            pLaunchMonInfo++;
            (*pNumLaunchMons)++;
            MaxLaunchMons--;

            if(MaxLaunchMons == 0)
            {
                return FS_SUCCESS;
            }
        } 
    }
    return FS_SUCCESS;
}

C#:

        [DllImport("FSADLL", SetLastError = false)]
        private static extern int FS_GetLMs([Out] IntPtr pLaunchMonInfo, int MaxLaunchMons, ref int pNumLaunchMons);


        [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] //, Size = 38)]
        public struct FS_LMON_STATUS
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FS_MAX_FIRMWARE_VER)] //10 bytes
            public string FirmwareVers;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FS_MAX_SERIAL_NUM)] // 15 bytes
            public string SerialNum;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = FS_MAX_HW_VER)] // 5 bytes
            public string HardwareVers;

            public uint StatusFlags; //4 bytes
            public int LMIndex;     // identifies which index //4 bytes
        }


            const int max_launch_monitors = 8;
            FS_LMON_STATUS[] dev_info =  new FS_LMON_STATUS[max_launch_monitors];
            int num_launch_monitors = 0;

            IntPtr pAddr = Marshal.AllocHGlobal(max_launch_monitors * Marshal.SizeOf(typeof(FS_LMON_STATUS)));
            Marshal.StructureToPtr(dev_info, pAddr, false);

            int result = FS_GetLMs(pAddr, max_launch_monitors, ref num_launch_monitors);
            UnityEngine.Debug.Log("Result of FS_GetLMs: " + result);

            FS_LMON_STATUS[] device_info = new FS_LMON_STATUS[max_launch_monitors];

            //Marshal.Copy(pAddr, device_info, (int)0, num_launch_monitors * (int)Marshal.SizeOf(typeof(FS_LMON_STATUS)));
            //Marshal.ReadIntPtr(pAddr, 0);
            //device_info = (FS_LMON_STATUS[]) Marshal.PtrToStructure(Marshal.AllocHGlobal(max_launch_monitors * Marshal.SizeOf(typeof(FS_LMON_STATUS[]))), typeof(FS_LMON_STATUS[]));

            if (num_launch_monitors > 0)
                UnityEngine.Debug.Log("GC2 Device Found.");
            else // If there is no devices found, remove the previous device from the holder variable 
                GC2Device = null;

            for (int i = 0; i < num_launch_monitors; i++)
            {
                device_info[i] = (FS_LMON_STATUS)Marshal.PtrToStructure(pAddr, typeof(FS_LMON_STATUS));
                pAddr = new IntPtr(Marshal.SizeOf(typeof(FS_LMON_STATUS)) + pAddr.ToInt64());
            }

            //*** There will only ever be 1 device in the list until the old SDK is fixed ***
            for (int lm_index = 0; lm_index < num_launch_monitors; lm_index++)
            {
                if (device_info[lm_index].StatusFlags != LM_STATUS_DISCONNECTED)
                {

                    UnityEngine.Debug.Log("device_info.SerialNum: " + device_info[lm_index].SerialNum);


                    //assign each LM to a LM data structure
                    LaunchMonitor logical_device = new LaunchMonitor(inst);
                    logical_device.mLaunchMonitorType = LaunchMonitorType.LAUNCH_MONITOR_TYPE_GC2;
                    logical_device.mConnectionType = ConnectionType.USB_CONNECTION;


                    IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(device_info[lm_index]));
                    Marshal.StructureToPtr(device_info[lm_index], pnt, false);
                    //Marshal.Copy(device_info[lm_index], dv_info, 0, (uint)Marshal.SizeOf(typeof(FS_LMON_STATUS)));

                    logical_device.mConnectionToken = pnt;
                    //GC2Devices.Add(logical_device);

                    logical_device.Serial = logical_device.GetSerialNumber();
                    GC2Device = logical_device;

                }
            }

原来问题出在C ++端,所有编组的东西都是正确的。 感谢提示汉斯。

链接地址: http://www.djcxy.com/p/66605.html

上一篇: Marshaling Struct Array with Strings Between c# and c++. Strings are empty

下一篇: Marshaling a C++ Struct with fixed size 2D char array from C#