2010-04-05 3 views
5

Mon programme natif C++ Win32 engendre un processus de travail et doit lui transmettre une énorme chaîne de configuration. Actuellement, il transmet simplement la chaîne en tant que ligne de commande à CreateProcess(). Le problème est que la chaîne s'allonge et qu'elle ne correspond plus à la limitation de 32 Ko imposée par Windows. Bien sûr, je pourrais faire quelque chose comme compliquer le début du processus de travail - j'utilise le serveur RPC de toute façon et je pourrais introduire une requête RPC pour passer la chaîne de configuration, mais cela nécessitera beaucoup de changements et rendra la solution pas si fiable. L'enregistrement des données dans un fichier pour le passage n'est pas très élégant - le fichier pourrait être laissé sur le système de fichiers et devenir corrompu.Comment passer facilement une très longue chaîne à un processus de travail sous Windows?

Quelles sont les autres manières simples de passer de longues chaînes à un processus de travail démarré par mon programme sous Windows?

+0

IPC pris en charge par Windows: http://msdn.microsoft.com/en-us/library/aa365574%28v=VS.85%29.aspx –

Répondre

1

Utilisation de la mémoire partagée. Passez à un nom de processus de travail de l'objet de mémoire partagée. Une autre solution consiste à utiliser le message WM_COPYDATA.

6

Une stratégie possible consiste à créer un named Pipe et à transmettre le handle (ou le nom du canal) à l'autre processus. Utilisez ensuite les opérations de lecture/écriture normales sur Pipe pour extraire les données.

6

Il existe déjà plusieurs bonnes réponses, mais la façon la plus simple est de l'enregistrer dans un fichier, et de passer le nom du fichier dans la ligne de commande. En plus d'être simple, un avantage de cette approche est que les applications seront très faiblement couplées (vous serez potentiellement capable d'utiliser l'application enfant de manière autonome, plutôt que de toujours la lancer) à partir d'un programme qui sait comment y insérer des données via une interface spécialisée)

Si vous voulez être sûr que le fichier est nettoyé après le traitement, marquez-le pour la suppression au prochain redémarrage. Si quelqu'un oublie de le nettoyer, le système d'exploitation s'en chargera au prochain redémarrage.

1

Que diriez-vous de le lire de stdin :) Il semble fonctionner pour les gens Unix.

Garantit beaucoup plus facile que de passer les noms de tuyaux/poignées autour!

Voici quelques official code de MSDN pour la création de processus enfants avec des canaux d'E/S.

4

Je préférerais la file d'attente de messages de Boost. C'est extrêmement simple mais sophistiqué. Voici un exemple:


#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

Vous pouvez utiliser un handle héritable pour un objet section. Dans votre processus parent, créez un objet section (CreateFileMapping) et spécifiez que son handle doit être hérité par le processus fils; puis passez la valeur du handle au processus enfant sur la ligne de commande. Le processus enfant peut alors ouvrir l'objet section (OpenFileMapping). Bien que je préférerais un objet de section nommé comme la sémantique de l'utiliser est plus facile à comprendre.

Questions connexes