2017-01-30 16 views
0

Я пытаюсь отправить строку из C++/CLI в C#/WinFormsОтправить Струнные от C++ для процессов C# с использованием WndProc

Вот мой PostMessage

void Browser::NavigateTo(System::String^ address){ 
    GCHandle gch = GCHandle::Alloc(address, GCHandleType::Pinned); 
    auto GCPin = gcHandle.AddrOfPinnedObject(); 
    ::PostMessage(procWndHandle, WM_NAVTO, 0, (LPARAM &GCPin); 
} 

В Winform функции, я» м, пытаясь выстроить его как этот

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust"] 
protected override void WndProc(ref Message m) 
switch (m.Msg) { 
    case WM_NAVTO: 
     string s = Marshal.PtrToStringUni(m.LParam); 
     break; 
    } 
} 

Я не получаю исключение, однако я не получаю адрес я послал, вместо этого я получаю Unicode Garbage.

Уверен, что у меня нет чего-то фундаментального, но я не вижу его. Может ли кто-нибудь помочь?

+1

Просто чтобы уточнить: C++/CLI и C# являются полностью отдельными процессами? –

+1

, если код C++/CLI и C# находится в отдельных процессах, вам необходимо выделить глобальную память. –

+2

Правильно, это фундаментально. Только системные сообщения могут автоматически сортироваться по границам процесса. ОС не знает, что может означать WM_NAVTO и как нужно обрабатывать ее аргументы. WM_COPY будет работать. Рассмотрите именованный канал как самое превосходное решение. –

ответ

5

Там есть пара проблемы с текущим кодом:

  1. PostMessage не ждет принимающей заявки, прежде чем вернуться. Следовательно, закрепленный объект становится незакрепленным до того, как сообщение будет обработано и может быть перенесено в новое место в памяти. (Это, вероятно, не является главной проблемой здесь.)
  2. Предполагая, что ваши компоненты на C++/CLI и C# являются полностью отдельными процессами, то, что вы делаете, отправляет указатель в одном пространстве процесса на другой процесс. Этот указатель уже недействителен.

Чтобы исправить # 2, вам нужно как-то скопировать память из одного процесса в другой.

  1. Как указал Ханс Пассант в комментариях, вы можете использовать именованный канал для отправки любых данных, которые вам нравятся в другом приложении. Это, вероятно, лучшее решение, и, безусловно, самое полнофункциональное.
  2. Если вам нужно придерживаться сообщений Windows, используйте сообщение WM_COPYDATA. В этом сообщении Windows будет копировать ваши данные (содержимое строки в этом случае) из одного процесса в другой. См. Пример Using Data Copy на MSDN.
+0

, конечно, если оба C++/CLI и C# находятся в одном и том же * процессе, это все ** в принципе ** проще. –