如何轻松地将非常长的字符串传递给Windows下的工作进程?

时间:2010-04-05 07:14:26

标签: c++ windows visual-c++ interop

我的本​​机C ++ Win32程序产生一个工作进程,需要向它传递一个巨大的配置字符串。目前它只是将字符串作为命令行传递给CreateProcess()。问题是字符串越来越长,现在它不适合Windows强加的32K字符限制。

当然我可以做一些事情,比如复杂的工作进程启动 - 无论如何我在其中使用RPC服务器,我可以引入一个RPC请求来传递配置字符串,但这需要进行大量更改并使解决方案不能太可靠了将数据保存到文件中以便传递也不是很优雅 - 文件可能会留在文件系统上而变成垃圾。

还有哪些简单的方法可以将长字符串传递给我在Windows上的程序启动的工作进程?

7 个答案:

答案 0 :(得分:6)

一种可能的策略是创建named Pipe并将句柄(或管道名称)传递给另一个进程。然后在Pipe上使用正常的Read \ Write操作来提取数据。

答案 1 :(得分:6)

已有几个好的答案,但最简单的方法是将其保存在文件中,并在命令行中传递文件名。

除了简单之外,这种方法的一个优点是应用程序将非常松散地耦合(您可能能够以其他方式独立使用子应用程序,而不是始终必须从一个知道如何通过专用接口将数据传输到其中的程序

如果要确保在处理后清除文件,请在下次重新启动时将其标记为删除。如果有人忘记清理它,操作系统会在下次重启时为你处理它。

答案 2 :(得分:4)

我更喜欢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 &) {
        // ...
}

答案 3 :(得分:1)

使用共享内存。传递给共享内存对象的工作进程名称。另一种解决方案是使用WM_COPYDATA消息。

答案 4 :(得分:1)

如何从stdin读取它:)它似乎适用于Unix人员。

保证比传递管道名称/句柄更容易!

以下是来自MSDN的一些official code,用于使用I / O管道创建子进程。

答案 5 :(得分:0)

是否可以设置命名的共享内存段?

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

答案 6 :(得分:0)

您可以对section对象使用可继承的句柄。在父进程中创建一个section对象(CreateFileMapping)并指定它的句柄将由子进程继承;然后将句柄值传递给命令行上的子进程。然后,子进程可以打开section对象(OpenFileMapping)。虽然我更喜欢命名的section对象,因为使用它的语义更容易理解。