2010-04-05 12 views
5

Mein natives C++ Win32-Programm erzeugt einen Worker-Prozess und muss ihm eine große Konfigurationszeichenfolge übergeben. Zur Zeit übergibt es die Zeichenfolge als Befehlszeile an CreateProcess(). Das Problem ist, dass die Zeichenkette länger wird und jetzt nicht mehr in die 32K-Zeichen-Beschränkung von Windows passt.Wie kann man einen sehr langen String problemlos an einen Worker-Prozess unter Windows übergeben?

Natürlich könnte ich etwas wie komplizieren den Worker-Prozess starten - ich benutze den RPC-Server trotzdem und ich könnte eine RPC-Anfrage für die Übergabe der Konfigurations-String einführen, aber dies wird eine Menge Änderungen erfordern und die Lösung machen nicht so zuverlässig. Das Speichern der Daten in einer Datei zum Übergeben ist auch nicht sehr elegant - die Datei könnte im Dateisystem verbleiben und zu einem Müll werden.

Welche anderen einfachen Möglichkeiten gibt es für die Übergabe langer Zeichenfolgen an einen Arbeitsprozess, der von meinem Programm unter Windows gestartet wurde?

+0

IPC von Windows unterstützt: http://msdn.microsoft.com/en-us/library/aa365574%28v=VS.85%29.aspx –

Antwort

1

Verwendung Shared Memory. An einen Worker-Prozessnamen des Shared-Memory-Objekts übergeben. Eine andere Lösung ist die Verwendung der Nachricht WM_COPYDATA.

6

Eine mögliche Strategie besteht darin, eine named Pipe zu erstellen und das Handle (oder den Pipe-Namen) an den anderen Prozess zu übergeben. Verwenden Sie dann normale Read \ Write-Operationen für Pipe, um die Daten zu extrahieren.

6

Es gibt bereits mehrere gute Antworten, aber die einfachste Weise ist es in einer Datei zu speichern, und übergeben Sie den Dateinamen in der Befehlszeile. Ein Vorteil dieses Ansatzes ist, dass die Apps sehr lose gekoppelt sind (Sie können möglicherweise die untergeordnete Anwendung auf andere Weise eigenständig verwenden, anstatt sie immer starten zu müssen.) von einem Programm, das über eine spezielle Schnittstelle Daten dorthin leiten kann)

Wenn Sie sichergehen möchten, dass die Datei nach der Verarbeitung bereinigt wird, markieren Sie sie beim nächsten Neustart zum Löschen. Wenn jemand vergisst, es aufzuräumen, wird das Betriebssystem es beim nächsten Neustart für Sie erledigen.

1

Wie wäre es mit dem Lesen von stdin :) Es scheint für die Unix-Leute zu arbeiten.

Garantiert viel einfacher als Pipe Namen/Griffe zu übergeben!

Hier sind einige official code von MSDN zum Erstellen untergeordneter Prozesse mit E/A-Pipes.

4

Ich würde Boost Nachrichtenwarteschlange bevorzugen. Es ist extrem einfach, aber raffiniert. Hier ist Beispiel:


#include <boost/interprocess/ipc/message_queue.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/shared_ptr.hpp> 

using namespace boost::interprocess; 

// ------------------------------------------------------------------------------ 
// Your worker: 
// ------------------------------------------------------------------------------ 

try { 
     message_queue::remove("NAME_OF_YOUR_QUEUE"); 

     boost::shared_ptr<message_queue> mq(new message_queue(create_only, "NAME_OF_YOUR_QUEUE", 65535, 32)); 

     char message[1024]; 
     std::size_t size_received; 
     unsigned int priority; 

     if (mq->timed_receive(&message, sizeof(message), size_received, priority, boost::posix_time::ptime(boost::posix_time::second_clock::universal_time()) + boost::posix_time::seconds(1))) { 
       std::string s(message); // s now contains the message. 
     } 
} catch (std::exception &) { 
     // ... 
} 

// ------------------------------------------------------------------------------ 
// And the sender: 
// ------------------------------------------------------------------------------ 

try { 
     boost::shared_ptr<message_queue> mq(new message_queue(create_only, "NAME_OF_YOUR_QUEUE", 1024, 1024)); 
     std::stringstream message; 

     message << "the very very very long message you wish to send over"; 

     while (!mq.try_send(message.str().c_str(), message.str().length(), 0)) 
       ::Sleep(33); 
} catch (std::exception &) { 
     // ... 
} 
0

Sie könnten einen vererbbaren Handle zu einem Abschnitt Objekt verwenden. Erstellen Sie in Ihrem übergeordneten Prozess ein Abschnittsobjekt (CreateFileMapping), und geben Sie an, dass dessen Handle vom untergeordneten Prozess geerbt werden soll. Übergeben Sie dann den Handle-Wert an den untergeordneten Prozess in der Befehlszeile. Der untergeordnete Prozess kann dann das Abschnittsobjekt (OpenFileMapping) öffnen. Obwohl ich ein benanntes Sektionsobjekt bevorzugen würde, da die Semantik seiner Verwendung einfacher zu verstehen ist.

Verwandte Themen