实现的功能: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