繁体   English   中英

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

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

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

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

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

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

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

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

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

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

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

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

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

以下是MSDN中用于使用I / O管道创建子进程的一些官方代码

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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