簡體   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