“尝试读取写保护存储器...”将结构编组到指针时出错

发布于 12-19 08:33 字数 726 浏览 3 评论 0原文

我正在测试一个简单的概念,其中有一个名为 ChatMessage 的结构,其中包含 2 个字节数组(MessageText 长度 512 和 UserName 长度 32)和一个 DateTime。我将字符串参数传递给 ChatMessage 构造函数,并将它们转换为字节数组,然后设置 DateTime。在构造对象后,我这样做:

ChatMessage chat = new ChatMessage("Message", "Username");
IntPtr m = Marshal.AllocHGlobal(Marshal.SizeOf(chat));
Marshal.StructureToPtr(chat, m, true);
SendMessage(...);
Marshal.FreeHGlobal(m);

看起来应该非常简单。创建该结构的实例,将其编组到非托管内存并获取指针。我这样做是为了可以使用 Windows 消息将其传递给另一个程序。问题是,每当它到达 StructureToPtr() 行时,它都会抛出 AccessViolationException ,指出我“尝试读取或写入受保护的内存...”。我不知道我到底做错了什么。我知道我以前做过这个,但我只是找不到我在其中执行此操作的项目。

我只想将结构封送到非托管内存并将指向它的指针传递给另一个程序,然后将其封送到托管内存并读它。结构定义存在于两个项目中,所以这不是问题。

I'm testing a simple concept where I have a structure called ChatMessage that contains 2 byte arrays (MessageText length 512 and UserName length 32) and a DateTime. I pass string arguments to the ChatMessage constructor and convert them to byte arrays, then set the DateTime. After I construct the object I do this:

ChatMessage chat = new ChatMessage("Message", "Username");
IntPtr m = Marshal.AllocHGlobal(Marshal.SizeOf(chat));
Marshal.StructureToPtr(chat, m, true);
SendMessage(...);
Marshal.FreeHGlobal(m);

Seems like it should be pretty straightforward. Create an instance of the struct, marshal it to unmanaged memory and get the pointer. I'm doing it so I can pass it to another program using Windows Messages. the problem is, whenever it gets to the StructureToPtr() line, it throws an AccessViolationException stating that I "Attempted to read or write protected memory...". I don't know what the heck I'm doing wrong. I know I've done this before but I just can't find the project that I did it in.

I just want to marshal the struct to unmanaged memory and pass a pointer to it to another program, then marshal it to managed memory and read it. The struct definition exists in both projects, so that isn't the issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌2024-12-26 08:33:28

您正在使用 StructureToPtr 将数据从托管代码编组到非托管代码。如上所述,这不能跨进程工作。

您正在寻找的是一种通过跨进程或跨机器的线路序列化和发送“脱水”对象的方法。查看 MSDN 序列化内容。 Codeproject 对此也有一篇很好的文章 (http://www.codeproject.com/KB/cs/objserial.aspx)。

这应该可以帮助您开始。当然,如果您希望在大规模/高性能场景中传输此类数据,您可能需要查看类似 .NET 的协议缓冲区 或其他现代序列化框架。

You are marshalling data from managed to unmanaged code by using StructureToPtr. That does not work cross process as noted above.

What you're looking for is a way to serialize and send "dehydrated" objects over the wire cross-process or cross-machine. Take a look at the MSDN Serialization content. Codeproject also has a good article (http://www.codeproject.com/KB/cs/objserial.aspx) on this.

This should get you started. Of course, if you're looking to transmit this kind of data in high-scale/high-performance scenarios you probably want to look at something like Protocol Buffer for .NET or other modern serialization frameworks.

孤独患者2024-12-26 08:33:28

您正在跨进程发送消息,因此需要系统将数据从一个虚拟地址空间编组到另一个虚拟地址空间。对 Windows 消息执行此操作的唯一方法是发送 WM_COPYDATA 消息。如果您这样做,那么系统将处理跨进程问题。它不能与自定义消息一起使用。

但是,如果您希望进行大量的进程间通信,那么您应该像其他人所建议的那样寻找更高级别的机制。

You are sending messages cross-process so you need the system to marshal the data from one virtual address space to the other. The only way to do so with Windows messages is to send the WM_COPYDATA message. If you do that then the system will take care of the cross-process issues. It cannot work with a custom defined message.

But if you are wishing to do any serious amounts of inter-process communication then you should look for a higher level mechanism, as suggested by others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文