2012-05-16 5 views
6

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

Я желаю, чтобы иметь полную связь между моим VB.net процессом и моим процессом C++. Я хотел бы иметь возможность отправить строку в и из процесса C++, но на данный момент мне нужно достичь:

Отправку строку в процесс C++ и обращение с ним.

Это создает некоторые моменты, которые я не уверен, но я постараюсь это так просто, как это возможно ...

Используя следующую функцию декларации в VB;

Declare Function PostMessage Lib "user32" Alias "PostMessageA" (_ 
    ByVal hWnd As IntPtr, _ 
    ByVal Msg As UInteger, _ 
    ByVal wParam As IntPtr, _ 
    ByVal lParam As String _ 
) As Boolean 

И отправьте сообщение так;

PostMessage(hWnd, SM_PING, Nothing, "schlampe") 

Со следующим объявлением методы для захвата сообщения в C++;

LRESULT CALLBACK newWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 

И для проверки того, могу ли я получить доступ к строке с использованием;

char buffer[50]; 
sprintf(buffer, "Received: %s", (char *)lParam); 
MsgBox(buffer); 


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

Моя проблема заключается в том, что сообщение является получил и «обрабатываются» ... но окно сообщения, созданные в процессе C++ не содержит мое тестовое сообщение (оно гласит: «ПОЛУЧАЛ:»).

Итак, как я могу отправить строку через PostMessage/SendMessage с VB на C++?




Решение:

Смотрите принятый ответ на решение ... но, кроме того, вот как я получаю строку (C++):

LRESULT CALLBACK newWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    switch(uMsg) { 
     case WM_COPYDATA: 
      MsgBox("Received a WM_COPYDATA message"); 
      COPYDATASTRUCT * pcds = (COPYDATASTRUCT *)lParam; 
      LPCTSTR lpszString = (LPCTSTR)(pcds->lpData); 
      MsgBox(lpszString); 
      return 1L; 
    } 
    return CallWindowProc(instance->OriginalProcessor(), hwnd, uMsg, wParam, lParam); 
} 


И, наконец, я использовал пример IPC here - отправьте сообщение. Этот пример отправляет сообщение с использованием C#, но концепция была всем, что мне нужно (не говоря уже о том, что это прогулка в парке для преобразования такого кода в VB). Обратите внимание, что в моей реализации VB мне не нужно было прекращать строку с нулевым символом.

+0

Требуется ли использование специальных сообщений окна? Или передача данных между процессами является конечной целью? Для последнего существуют [лучшие способы] (http://en.wikipedia.org/wiki/Inter-process_communication), чтобы достичь этого. – ulidtko

+2

Прежде чем использовать его, вы, вероятно, должны сделать базовую проверку 'COPYDATASTRUCT'. Некоторое вредоносное приложение может отправлять вам фиктивные сообщения WM_COPYDATA. – jamesdlin

ответ

6

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

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

Несмотря на то, что между процессами с сообщениями Windows существуют другие способы, такие как обмен данными между процессами, WM_COPYDATA является самым простым. Если ваше требование становится намного более сложным, вам может потребоваться рассмотреть более всеобъемлющий подход IPC, чем сообщения Windows.

+0

Я бы обязательно упомянул об общих способах IPC: трубах, общей памяти + мьютексах, сокетах и ​​т. Д. – ulidtko

+1

@ulidtko Я исследовал другие методы, и я пришел к выводу, что сообщения в Windows вызовут мне меньше хлопот, но спасибо за ваша забота. – Spooky

+0

Нужно ли использовать 'OnCopyData' для получения данных? Важно отметить, что моя C++ DLL вводится в другой процесс, и я не уверен, могу ли я еще получить COPYDATASTRUCT – Spooky