Как легко передать очень длинную строку в рабочий процесс под Windows? - PullRequest
5 голосов
/ 05 апреля 2010

Моя родная программа C ++ Win32 порождает рабочий процесс, и ему нужно передать ему огромную строку конфигурации. В настоящее время он просто передает строку в виде командной строки на CreateProcess(). Проблема в том, что строка становится длиннее, и теперь она не вписывается в ограничение 32K символов, наложенное Windows.

Конечно, я мог бы сделать что-то вроде усложнения запуска рабочего процесса - я все равно использую в нем RPC-сервер и мог бы ввести RPC-запрос для передачи строки конфигурации, но это потребует большого количества изменений и сделает решение не так надежно Сохранение данных в файл для передачи также не очень элегантно - файл может остаться в файловой системе и стать мусором.

Какие есть еще простые способы передачи длинных строк в рабочий процесс, запущенный моей программой в Windows?

Ответы [ 7 ]

6 голосов
/ 05 апреля 2010

Уже есть несколько хороших ответов, но самый простой способ - сохранить его в файл и передать имя файла в командной строке.

Помимо простоты, преимущество этого подхода заключается в том, что приложения будут очень слабо связаны (потенциально вы сможете использовать автономное дочернее приложение другими способами, а не всегда запускать его из программа, которая знает, как передавать данные в нее через специализированный интерфейс)

Если вы хотите быть уверены, что файл очищен после обработки, отметьте его для удаления при следующей перезагрузке. Тогда, если кто-нибудь забудет его почистить, ОС примет это во внимание при следующей перезагрузке.

6 голосов
/ 05 апреля 2010

Одна из возможных стратегий - создать с именем Pipe и передать дескриптор (или имя канала) другому процессу. Затем используйте обычные операции чтения \ записи в Pipe для извлечения данных.

4 голосов
/ 05 апреля 2010

Я бы предпочел очередь сообщений Boost. Это очень просто, но сложно. Вот пример:


#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 &) {
        // ...
}
1 голос
/ 05 апреля 2010

Как насчет чтения из stdin :) Кажется, это работает для людей Unix.

Гарантировано намного проще, чем передавать имена / хэндлы труб!

Вот некоторый официальный код из MSDN для создания дочерних процессов с каналами ввода / вывода.

1 голос
/ 05 апреля 2010

Использовать разделяемую память.Передайте рабочему процессу имя разделяемой памяти.Другое решение - использовать сообщение WM_COPYDATA .

0 голосов
/ 05 апреля 2010

Вы можете использовать наследуемый дескриптор объекта раздела. В своем родительском процессе создайте объект раздела (CreateFileMapping) и укажите, что его дескриптор должен наследоваться дочерним процессом; затем передайте значение дескриптора дочернему процессу в командной строке. Затем дочерний процесс может открыть объект раздела (OpenFileMapping). Хотя я бы предпочел объект именованного раздела, так как семантика его использования более понятна.

0 голосов
/ 05 апреля 2010

Есть ли возможность настроить именованный сегмент совместно используемой памяти?

http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...