C#调用C++dll,返回值为结构体,结构体值转换不对

时间:2022-08-30 20:00:36
 C++dll的方法为   LPECWATCHDATA  WINAPI  ecwGetExternsionData(WORD widx);
LPECWATCHDATA是这样定义的 
typedef struct {
    WORD     nState;               //状态
    WORD     nIdx;                 //索引
    WORD     wDataCnt;             //数据(lpData)项数
    char     szTime[20];           //时间
    unsigned char* lpIDString;     //设备号码
    unsigned char* lpNameString;   //设备/用户名称
    LPCTSTR  lpData[8];
}ECWATCHDATA,*LPECWATCHDATA;  

我在C#里是这样转的    ECWATCHDATAeds = (ECWATCHDATA)(Marshal.PtrToStructure(ecwGetExternsionData(i), typeof(ExteECWATCHDATA)));     ExternsionDataStruct是我自己定义的一个结构体,结构体为
    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
    public struct ECWATCHDATA
    {

        /// WORD->unsigned short
        public ushort nState;

        /// WORD->unsigned short
        public ushort nIdx;

        /// WORD->unsigned short
        public ushort wDataCnt;

        /// char[20]
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 20)]
        public string szTime;

        /// char*
        public IntPtr lpIDString;

        /// char*
        public IntPtr lpNameString;

        /// char*[8]
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = System.Runtime.InteropServices.UnmanagedType.SysUInt)]
        public System.IntPtr[] lpData;
    }
  ECWATCHDATAeds = (ECWATCHDATA)(Marshal.PtrToStructure(ecwGetExternsionData(i), typeof(ECWATCHDATA))); 转化C#的结构体后里面有的值不对。像lpIDString,lpNameString和实际值对不上,这是什么原因?

7 个解决方案

#1


返回 IntPtr 之后,需要从非托管内存复制到托管内存。
你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。

#3


引用 1 楼 Saleayas 的回复:
返回 IntPtr 之后,需要从非托管内存复制到托管内存。
你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。

我已经用了Marshal.PtrToStringAnsi这个方法转换,但是出现了乱码,用这个函数转换有问题吗?

#4


我建议你检测一下你的 C 的 dll 是否正确返回了。
使用 C 语言测试一下这个结果。
返回一个结构的指针总归不是一个好的想法。

#5


引用 4 楼 Saleayas 的回复:
我建议你检测一下你的 C 的 dll 是否正确返回了。
使用 C 语言测试一下这个结果。
返回一个结构的指针总归不是一个好的想法。
这个是C++的dll里的方法,别人用C++调用这个dll返回的值没有问题,我不会用C++,只能用C#,C#返回的值和别人的那个C++返回值是字符串类型的值对不上

#6


public IntPtr lpIDString;
换成StringBuilder试试看

#7


引用 6 楼 mjp1234airen4385 的回复:
public IntPtr lpIDString;
换成StringBuilder试试看
不行,用了StringBuilder就出错了

#1


返回 IntPtr 之后,需要从非托管内存复制到托管内存。
你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。

#2


#3


引用 1 楼 Saleayas 的回复:
返回 IntPtr 之后,需要从非托管内存复制到托管内存。
你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。

我已经用了Marshal.PtrToStringAnsi这个方法转换,但是出现了乱码,用这个函数转换有问题吗?

#4


我建议你检测一下你的 C 的 dll 是否正确返回了。
使用 C 语言测试一下这个结果。
返回一个结构的指针总归不是一个好的想法。

#5


引用 4 楼 Saleayas 的回复:
我建议你检测一下你的 C 的 dll 是否正确返回了。
使用 C 语言测试一下这个结果。
返回一个结构的指针总归不是一个好的想法。
这个是C++的dll里的方法,别人用C++调用这个dll返回的值没有问题,我不会用C++,只能用C#,C#返回的值和别人的那个C++返回值是字符串类型的值对不上

#6


public IntPtr lpIDString;
换成StringBuilder试试看

#7


引用 6 楼 mjp1234airen4385 的回复:
public IntPtr lpIDString;
换成StringBuilder试试看
不行,用了StringBuilder就出错了