Передача указателей другому процессу

Я пытаюсь передать указатель на структуру в другой процесс, который я создал… Я получаю только ошибки недопустимого указателя в процессе, который я тоже отправляю… Возможно ли это вообще в .NET?

Мой код для процесса отправки:

' Initialize unmanged memory to hold the struct.
Dim ptrSettings As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(EngineSettings))

' Copy the struct to unmanaged memory.
Marshal.StructureToPtr(EngineSettings, ptrSettings, False)

SendMessage(HWND, MSG_SETTINGS_STRUCT, 0, ptrSettings)

Я переопределяю WinProc во втором процессе, чтобы получить сообщение в LParam:

EngineSettings = CType(Marshal.PtrToStructure(ptr, GetType(SettingsStruct)), SettingsStruct)

' Free the unmanaged memory.
Marshal.FreeHGlobal(ptr)

Указатель имеет одно и то же значение между обоими процессами, вот ошибка во втором процессе:

Код ошибки 0xc0000005. Эта ошибка может быть ошибкой в ​​среде CLR или в небезопасных или непроверяемых частях пользовательского кода. Распространенными источниками этой ошибки являются ошибки маршалинга пользователя для COM-interop или PInvoke, которые могут повредить стек.


person devHead    schedule 16.08.2012    source источник
comment
Я предполагаю, что вы столкнулись с защитой памяти, а это значит, что вам придется найти другой способ связи с другим процессом. Кроме того, сама ваша идея кажется очень плохой идеей.   -  person Security Hound    schedule 16.08.2012
comment
если вы считаете, что это плохая идея, то почему бы не предложить другой подход?   -  person devHead    schedule 16.08.2012


Ответы (3)


Обычно процессы не могут совместно использовать память. Помните, что большинство адресов на самом деле являются виртуальными адресами и указывают не на физическое расположение оборудования, а на страницу и смещение.

Функции win32 возвращают указатели, поскольку они выполняются в адресном пространстве ваших процессов, а не в отдельном процессе.

Дополнительную информацию см. в разделе параметры управления памятью в Win32. о том, как все собственные вызовы фактически выделяют память в Win32 (по крайней мере, из кода пользовательского режима). Единственное, что не упомянуто на этой странице, это Поддержка больших страниц, которая создает нестандартные страницы и не может быть загружена на диск. С этими страницами может быть сложно работать даже на C/C++, поэтому я настоятельно рекомендую не использовать их из среды CLR.

Вы, вероятно, захотите использовать общую память, если хотите напрямую поделиться этой нативной структурой. Создание именованной общей памяти (Win32)

person NtscCobalt    schedule 16.08.2012
comment
хорошо, спасибо за предоставление более подробной информации ... Джастин также порекомендовал файлы с отображением памяти. - person devHead; 16.08.2012

Могу ли я предложить изучить файлы с отображением памяти для такого рода вещей? Посмотрите здесь:

http://msdn.microsoft.com/en-us/library/dd997372(v=vs.100).aspx

person Justin Harvey    schedule 16.08.2012
comment
интересный подход, я почитаю... мне бы очень хотелось узнать, возможна ли моя реализация в CLR... - person devHead; 16.08.2012
comment
@ Дон, это невозможно в Windows. AllocHGlobal не выделяет память из глобальной кучи. Этот термин предназначен только для устаревших целей. AllocHGlobal по-прежнему вызывает VirtualAlloc на любой платформе Win32. Глобальные кучи были частью 16-битной эры. - person NtscCobalt; 16.08.2012
comment
спасибо, некоторые термины, используемые MS, очень расплывчаты... вместе с документацией на MSDN... - person devHead; 16.08.2012

Сериализируйте класс в XML и SendMessage(WM_SETTEXT) в текстовое поле в другом приложении (вы можете довольно легко передать hwnd, используя свой текущий код, поскольку он просто длинный). Затем поместите слушателя в событие изменения текстового поля.

person Belmiris    schedule 16.08.2012
comment
Я понимаю, что вы пытаетесь сделать, но это не совсем тот подход, который я хочу использовать. Спасибо. - person devHead; 16.08.2012