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

sinat_28980305 2016-10-26 03:01:28
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和实际值对不上,这是什么原因?
...全文
1129 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
簫讠 2019-04-24
  • 打赏
  • 举报
回复
c++ 类型转c#类型 尽量用intptr类型 等c#里要用到的值 在把它给实例化 转来转去会出问题
  • 打赏
  • 举报
回复
结构体 就是 一个字节对应不上 都会出错, 很麻烦的, 人家INT 你也得是INT, 并且 你俩的INT 字节 还得一直。
qq_35772585 2019-04-24
  • 打赏
  • 举报
回复
CharSet = System.Runtime.InteropServices.CharSet.Ansi 接口 引用里面改成这个 CharSet = CharSet.Unicode
xian_wwq 2019-04-23
  • 打赏
  • 举报
回复
StructLayout特性支持三种附加字段:CharSet、Pack、Size。
设定 Pack = 1
战斗强 2018-08-31
  • 打赏
  • 举报
回复
我写的详细例子https://blog.csdn.net/qq385105501/article/details/82253725
sinat_28980305 2016-10-27
  • 打赏
  • 举报
回复
引用 6 楼 mjp1234airen4385 的回复:
public IntPtr lpIDString; 换成StringBuilder试试看
不行,用了StringBuilder就出错了
mjp1234airen4385 2016-10-27
  • 打赏
  • 举报
回复
public IntPtr lpIDString; 换成StringBuilder试试看
sinat_28980305 2016-10-27
  • 打赏
  • 举报
回复
引用 4 楼 Saleayas 的回复:
我建议你检测一下你的 C 的 dll 是否正确返回了。 使用 C 语言测试一下这个结果。 返回一个结构的指针总归不是一个好的想法。
这个是C++的dll里的方法,别人用C++调用这个dll返回的值没有问题,我不会用C++,只能用C#,C#返回的值和别人的那个C++返回值是字符串类型的值对不上
Saleayas 2016-10-26
  • 打赏
  • 举报
回复
我建议你检测一下你的 C 的 dll 是否正确返回了。 使用 C 语言测试一下这个结果。 返回一个结构的指针总归不是一个好的想法。
sinat_28980305 2016-10-26
  • 打赏
  • 举报
回复
引用 1 楼 Saleayas 的回复:
返回 IntPtr 之后,需要从非托管内存复制到托管内存。 你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。
我已经用了Marshal.PtrToStringAnsi这个方法转换,但是出现了乱码,用这个函数转换有问题吗?
Poopaye 2016-10-26
  • 打赏
  • 举报
回复
Saleayas 2016-10-26
  • 打赏
  • 举报
回复
返回 IntPtr 之后,需要从非托管内存复制到托管内存。 你需要再次使用类似的方法把 IntPtr 转换成你需要的字符串。

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧