简体   繁体   中英

How to easily pass a very long string to a worker process under Windows?

My native C++ Win32 program spawns a worker process and needs to pass a huge configuration string to it. Currently it just passes the string as a command line to CreateProcess() . The problem is the string is getting longer and now it doesn't fit into the 32K characters limitation imposed by Windows.

Of course I could do something like complicating the worker process start - I use the RPC server in it anyway and I could introduce an RPC request for passing the configuration string, but this will require a lot of changes and make the solution not so reliable. Saving the data into a file for passing is also not very elegant - the file could be left on the filesystem and become garbage.

What other simple ways are there for passing long strings to a worker process started by my program on Windows?

One possible strategy is to create a named Pipe and pass the handle ( or pipe name) to the other process. Then use normal Read\\Write operations on Pipe to extract the data.

There are several good answers already, but the easiest way is to save it in a file, and pass the filename in the command line.

As well as being simple, an advantage of this approach is that the apps will be very loosely coupled (you'll potentially be able to use the child application stand-alone in other ways, rather than always having to launch it from a program that knows how to pipe data into it via a specialised interface)

If you want to be sure that the file is cleaned up after processing, mark it for deletion on the next reboot. THen if anybody forgets to clean it up, the OS will deal with it for you on the next reboot.

I would prefer Boost's message queue. It's extremely simple yet sophisticated. Here's example:


#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 &) {
        // ...
}

Use shared memory. Pass to a worker process name of shared memory object. Another solution is to use WM_COPYDATA message.

How about reading it from stdin :) It seems to work for the Unix folks.

Guaranteed a lot easier than passing pipe names/handles around!

Here is some official code from MSDN for creating child processes with I/O pipes.

Is it a possibility to set up a named shared memory segment?

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

You could use an inheritable handle to a section object. In your parent process create a section object (CreateFileMapping) and specify that its handle is to be inherited by the child process; then pass the handle value to the child process on the command line. The child process can then open the section object (OpenFileMapping). Though I would prefer a named section object as the semantics of using it are easier to understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM