Ошибка «Попытка чтения из памяти, защищенной от записи ...» при маршалинге структуры в указатель - PullRequest
1 голос
/ 02 декабря 2011

Я тестирую простую концепцию, где у меня есть структура с именем ChatMessage, которая содержит 2-байтовые массивы (длина сообщения 512 и длина имени пользователя 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, в котором говорится, что я «пытался читать или записывать защищенную память ...».Я не знаю, какого чёрта я делаю не так.Я знаю, что делал это раньше, но я просто не могу найти проект, в котором я это сделал.

Я просто хочу упорядочить структуру в неуправляемую память и передать указатель на нее другой программе, затемнаправить его в управляемую память и прочитать.Определение структуры существует в обоих проектах, так что это не проблема.

Ответы [ 2 ]

4 голосов
/ 02 декабря 2011

Вы сортируете данные из управляемого в неуправляемый код с помощью StructureToPtr. Это не работает кросс-процесс, как отмечено выше.

То, что вы ищете, - это способ сериализации и отправки «обезвоженных» объектов по проводному кросс-процессу или кросс-машине. Взгляните на Сериализация MSDN . У Codeproject также есть хорошая статья (http://www.codeproject.com/KB/cs/objserial.aspx) об этом.

Это должно помочь вам начать. Конечно, если вы хотите передавать данные такого рода в высокопроизводительных / высокопроизводительных сценариях, вы, вероятно, захотите взглянуть на что-то вроде Protocol Buffer for .NET или других современных сред сериализации.

0 голосов
/ 02 декабря 2011

Вы отправляете сообщения в перекрестном процессе, поэтому вам необходимо, чтобы система перенаправила данные из одного виртуального адресного пространства в другое. Единственный способ сделать это с сообщениями Windows - это отправить сообщение WM_COPYDATA. Если вы сделаете это, то система позаботится о проблемах межпроцессного взаимодействия. Он не может работать с пользовательским сообщением.

Но если вы хотите делать какие-то серьезные межпроцессные коммуникации, вам следует искать механизм более высокого уровня, как это предлагают другие.

...