C# C++ 使用命名管道进行进程通信
实现的功能:C#和C++的应用程序运行时,这两个进程间可以进行进程通信,互相发送和接收消息。
之前看了很多网上的代码写进程通信,大多数都是讲C#——C#或C++——C++这种相同类型的应用程序间的通信,很少有C#->C++或C++->C#这种不同类型的应用程序间的通信。但仔细想想,系统中的进程通过创建、连接管道(Pipe)完成进程通信,那么这个创建、连接的过程,张三有张三的创建方法,李四有李四的连接方法,但这有什么关系呢,它们最终达到的结果一致就可以了。因此,在实现C#和C++之间的进程通信时,我们只需要用它们各自自己的方法来创建管道、连接管道,例如,我们以C#端为服务器端,以C++端为客户端,C#通过NamePipeServerStream创建管道,C++通过WaitNamedPipe和CreateFile等待连接管道,就能实现C#和C++进程间的进程通信。以下我们来详细讲诉。
首先,你必须要先了解C#和C++各自的管道通信机制,无论是作为客户端还是服务器,这样无论是哪种需求你都可以将其两两组合,达到你想要的效果。
C#:
服务器(NamePipeServerStream):https://docs.microsoft.com/zh-cn/dotnet/api/system.io.pipes.namedpipeserverstream?view=netframework-4.7.2
客户端(NamePipeClientStream):https://docs.microsoft.com/zh-cn/dotnet/api/system.io.pipes.namedpipeclientstream?view=netframework-4.7.2
C++:
可参见博客 :https://blog.csdn.net/u010797208/article/details/41566395
接下来,我们便可根据自己的目标需求将它们组合起来,示例以C#为服务器,以C++为客户端实现两者之间的通信,如下。
C# 服务器端:
NamedPipeServerStream m_pipe_server = null;
StreamWriter sw = null;
StreamReader sr = null;
/*点击按钮创建连接并发送消息*/
protected void onSendButtonClick(object sender, RoutedEventArgs e)
{
if (m_pipe_server == null)
{
m_pipe_server = new NamedPipeServerStream("mypipe");
m_pipe_server.WaitForConnection();
}
if (sw == null) { sw = new StreamWriter(m_pipe_server); sw.AutoFlush = true; }
if (sr == null) sr = new StreamReader(m_pipe_server);
sw.WriteLine("I am server.");
string srstr = sr.ReadLine();
this.TextBox1.Text = "hi:" + srstr;
}
C++ 客户端:
bool is_pipe_setup = false;
HANDLE pipe_client = nullptr;
/*客户端一直在等待服务器发起连接,管道创建成功后发送消息*/
while (1)
{
if(is_pipe_setup == false)
{
BOOL ret = WaitNamedPipe(TEXT("\\\\.\\Pipe\\mypipe"), NMPWAIT_WAIT_FOREVER);
if (ret)
{
pipe_client = CreateFile(
TEXT("\\\\.\\Pipe\\mypipe"),
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (pipe_client == INVALID_HANDLE_VALUE) continue;
else is_pipe_setup = true;
}
}
char readbuf[256] = "";
char writebuf[256] = "I am client, I am writing \n";
DWORD readlen = 0;
DWORD writelen = 0;
if (ReadFile(pipe_client, readbuf, sizeof(readbuf), &readlen, NULL) != FALSE)
cout << readbuf << endl;
if (WriteFile(pipe_client, writebuf, sizeof(writebuf), &writelen, NULL) != FALSE)
{
cout << "client write success" << endl;
}
两边的各个方面都要完全匹配对于。例如创建和等待连接的管道名称应该相同;一方发送数据另一方则接收数据等等。尤其要注意的一点是,当接收数据的一方使用Readline()函数读取管道数据时,发送方一定要注意发送的信息最后必须带有“\n”换行符!否则,接收方会一直认定接受数据尚未结束,一直处于等待接收状态,程序则无法继续运行下去!我写的时候被这个坑卡了很久。。。。
转载请注明出处!
谢谢~
本文地址:https://blog.csdn.net/SimonSmile/article/details/85273894