2012-05-16 18 views
6

Sebbene ci siano già alcune risorse online che affrontano questo argomento approssimativo, non ho ancora trovato una risposta che funzioni per me.
Invio/Ricezione di una stringa tramite PostMessage

ho desiderio di avere piena comunicazione tra il mio VB.net di processo e il mio processo di C++. Vorrei essere in grado di inviare una stringa di e dal processo di C++, ma per il momento ho bisogno di ottenere:

Invio una stringa al processo C++, e la manipolazione.

Questo crea alcuni punti che sono incerto, ma cercherò di mantenere questo più semplice possibile ...

Utilizzando la seguente dichiarazione di funzione in 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 

E inviare il messaggio in questo modo;

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

Con la seguente dichiarazione di metodo per catturare il messaggio in C++;

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

E per un test se è possibile accedere alla stringa utilizzando;

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


ho scremato su un sacco di dettagli che credo di essere inutile, ma chiedere e vi sarà dato a voi.

Il mio problema è che il messaggio è ricevuto e "gestito" ... ma la finestra di messaggio creato dal processo di C++ non contiene il mio messaggio di prova (si legge: "Ricevuto:").

Così, come posso inviare una stringa tramite PostMessage/SendMessage da VB a C++?




Soluzione:

Vedi la risposta accettata per la soluzione ... ma Inoltre, ecco come lo ricevo la stringa (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); 
} 


E, infine, ho usato l'esempio IPC here-invia il messaggio. Questo esempio invia il messaggio utilizzando C#, ma il concetto era tutto il necessario (per non parlare che si tratta di una passeggiata nel parco per convertire tale codice a VB). Si noti che nella mia implementazione VB, non avevo bisogno di terminare la stringa con un carattere null.

+0

L'esigenza di utilizzare i messaggi della finestra è specifica? O sta passando i dati tra i processi l'obiettivo finale? Per quest'ultimo, ci sono [modi migliori] (http://en.wikipedia.org/wiki/Inter-process_communication) per ottenerlo. – ulidtko

+2

Probabilmente dovresti fare alcune validazioni di base del 'COPYDATASTRUCT' prima di usarlo. Alcune applicazioni dannose potrebbero inviarti messaggi 'WM_COPYDATA' falsi. – jamesdlin

risposta

6

Quando si utilizzano i messaggi di Windows, è necessario utilizzare WM_COPYDATA per trasferire i dati di stringa tra i processi. Se si utilizzano ID messaggio personalizzati, i dati della stringa non verranno distribuiti tra i due distinti spazi degli indirizzi del processo.

E questo è il motivo per cui il codice corrente non funziona. Il processo di ricezione è passato a lParam un puntatore alla memoria nello spazio degli indirizzi dei processi chiamanti. E ovviamente non ha senso nell'altro processo.

Mentre esistono altri modi per eseguire il marshalling di dati come questo tra processi con messaggi Windows, WM_COPYDATA è di gran lunga il più semplice. Se i requisiti diventano molto più complessi, potrebbe essere necessario prendere in considerazione un approccio IPC più completo rispetto ai messaggi di Windows.

+0

Vorrei menzionare i modi generici di fare IPC: pipe, memoria condivisa + mutex, socket, ecc. – ulidtko

+1

@ulidtko Ho studiato altri metodi, e ho concluso che i messaggi di Windows mi avrebbero causato meno problemi, ma grazie per tua preoccupazione. – Spooky

+0

È necessario utilizzare 'OnCopyData' per ricevere i dati? È importante notare che la mia DLL C++ è iniettata in un altro processo, e non sono sicuro se posso ancora ricevere il 'COPYDATASTRUCT' – Spooky