如何获取WParam及LParam里的数据?

qq_41565588 2019-01-25 04:17:05
C++写的DLL,DLL通过消息发送数据过来,以下是VB的调用代码,想转成C#的,不知从何下手。我看了C#下的 Message的WParam及LParam都是IntPtr类型,传过来的数据应该是个指针吧,如何将他指向的内存的数据取出来呢?
Dim waveLen As Single
Dim waveValue As Single

Dim addrWL As Double
Dim addrWV As Double

Dim waveLenAddr As Double
Dim waveValueAddr As Double

addrWL = VarPtr(wParam)
addrWV = VarPtr(lParam)

waveLenAddr = VarPtr(waveLen)
waveValueAddr = VarPtr(waveValue)

CopyMemory waveLenAddr, addrWaveLen, 4
CopyMemory waveValueAddr, addrWaveValue, 4
...全文
651 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_41565588 2019-01-27
  • 打赏
  • 举报
回复
现在我能能过这样的方式得到我想要的结果(1120392206 是我的收到消息时lParam.toInt32的值) Int32 wl = new IntPtr(1120392206).ToInt32(); float waveLen =0; unsafe { Int32* wsrc = &wl; float* wdst = &waveLen; memmove(wdst, wsrc, 4); } 我想问的是,如果不用unsafe代码,要拖后腿实现呢?
threenewbee 2019-01-27
  • 打赏
  • 举报
回复
C#的marshal.copy类似copymemory,但是只能拷贝结构体 https://blog.csdn.net/qq_37855507/article/details/83684258
xuzuning 2019-01-27
  • 打赏
  • 举报
回复
你可以定义这样一个结构 struct MyStruct{public int a; } 然后用 GetLParam 读取 MyStruct myVal = new MyStruct(); Type myType=myType.GetType(); myVal = (MyStruct)m.GetLParam(myType);
qq_41565588 2019-01-27
  • 打赏
  • 举报
回复
调用的DLL是第三方写的(用的是DELPHI),发过来的是一个Cardinal类型的数据(无符号32位)。在收到消息时 用 Marshal.Copy(m.LParam, bytes, 0, length) 总是提示那样的错误,搞不清楚为什么。
xuzuning 2019-01-27
  • 打赏
  • 举报
回复
本来 C# 是约定用 Message.GetLParam 来读取的 但显然你们没有按照该约定,将 LParam 指向一个结构体 所以你的 vb.net 也使用了内存拷贝 CopyMemory 对应的 C# 就是 Marshal.Copy(m.LParam, bytes, 0, length)
qq_41565588 2019-01-27
  • 打赏
  • 举报
回复
实际上我直接用消息的LPARAM参数,然后使用 Marshal.Copy ,一直出现现 “其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏”这个错误,所以我不得不使用那段unsafe代码。
xuzuning 2019-01-27
  • 打赏
  • 举报
回复
是的,我也无法保证 p 指向的是有效的内存块,仅仅示例而已 但你的 LParam 是 Message 结构的成员,自然是有效的 而读取消息结构是有标准写法的,当然我给的也是其中之一
qq_41565588 2019-01-27
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
IntPtr p = 1120392206;
byte[] b = new byte[4];
Marshal.Copy(p, b, 0, 4);
var n = BitConverter.ToInt32(b, 0);
这样会提示 其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 错误
xuzuning 2019-01-27
  • 打赏
  • 举报
回复
IntPtr p = 1120392206;
byte[] b = new byte[4];
Marshal.Copy(p, b, 0, 4);
var n = BitConverter.ToInt32(b, 0);
吹风的兔子 2019-01-26
  • 打赏
  • 举报
回复
Win32 消息? 这就尴尬了, LParam 可能指向的是 任何结构体对象(内存块)。 所以,也就没有 通用代码。 你只有自己 区分 那些时候 转换成 哪些对象。 这里有段 参考代码:


                                NCCALCSIZE_PARAMS p = (NCCALCSIZE_PARAMS)m.GetLParam(typeof(NCCALCSIZE_PARAMS));  //读取 LParam 内存块
                                p.rect0.Top += offset.CaptionAndTopSize;
                                p.rect0.Bottom -= offset.BottomSize;
                                p.rect0.Left += offset.LeftSize;
                                p.rect0.Right -= offset.RightSize;
                                if (this.MdiParent != null) base.WndProc(ref m);

                                Marshal.StructureToPtr(p, m.LParam, false);  //将新值 覆盖到 LParam 内存块。

110,534

社区成员

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

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

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