C++进程间通信
# C++进程间通信 #
进程间通讯的四种方式:剪贴板、匿名管道、命名管道和邮槽
## 剪切板 ##
//设置剪切板内容
CString str;
this->GetDlgItemText(IDC_EDIT1, str);
OpenClipboard();//打开剪贴板查看,并防止其他应用程序修改剪贴板的内容.
EmptyClipboard();//EmptyClipboard Function该函数清空剪切板并释放剪切板内数据的句柄。函数在之后会将剪切板的所有权指派给当前打开剪切板的窗口。
HANDLE hclip = GlobalAlloc(GMEM_MOVEABLE, str.GetLength() + 1);
char *pBuf = (char *)GlobalLock(hclip);
//WideCharToMultiByte()//字形转换
strcpy(pBuf, str.GetBuffer());
//memcpy(pBuf, str.GetBuffer(), GetLength()+2);
GlobalLock(hclip);
SetClipboardData(CF_TEXT, hclip);//SetClipboardData是把指定数据按照指定格式放入剪切板中
CloseClipboard();//关闭剪贴板,这使其他窗口或程序能访问剪贴板。
//获得剪切板内容
OpenClipboard();
if (IsClipboardFormatAvailable(CF_TEXT))//是以NULL结尾的ASCII字符的文本格式,则该函数返回值为true,否则为false。
{
HANDLE hclip;
hclip = GetClipboardData(CF_TEXT);//用来打开剪贴板并获取剪贴板内容。
char *pBuf = (char *)GlobalLock(hclip);
GlobalUnlock(hclip);
CString STR;
SetDlgItemText(IDC_EDIT1, pBuf);
}
CloseClipboard();
//参考:
//http://bbs.kechuang.org/t/72605
//http://www.cnblogs.com/BoyXiao/archive/2010/12/25/1916677.html
## 匿名管道 ##
//父进程实现
//创建匿名管道
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
if (!CreatePipe(&m_hRead, &m_hWrite, &sa, 0))
{
AfxMessageBox(_T("create pipe error"));
}
//子进程的创建
STARTUPINFO sui;
PROCESS_INFORMATION pi;
sui.cb = sizeof(STARTUPINFO);
ZeroMemory(&sui, sizeof(STARTUPINFO));
sui.dwFlags = STARTF_USESTDHANDLES;
sui.hStdInput = m_hRead;
sui.hStdOutput = m_hWrite;
sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);
if (!CreateProcess(_T("../debug/child.exe"), NULL , NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi ))
{
AfxMessageBox(_T("创建子进程错误"));
}
//关闭进程 线程计数器
if (pi.hThread)
{
CloseHandle(pi.hThread);
}
if (pi.hProcess)
{
CloseHandle(pi.hProcess);
}
//发送数据
char buf[] = "this is pipe server";
DWORD dwWrite = 0;
if (!WriteFile(m_hWrite, buf, strlen(buf) + 1, &dwWrite, NULL))
{
AfxMessageBox(_T("write error parent"));
}
//接收数据
char buf[128] = {0};
DWORD dwRead = 0;
ReadFile(m_hRead, buf, sizeof(buf), &dwRead, NULL );
//子进程实现
//获取继承自父进程的匿名管道读写句柄
m_hRead = GetStdHandle(STD_INPUT_HANDLE);
m_hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
//写入数据
char buf[] = "this is pipe child";
DWORD dwWrite = 0;
if (!WriteFile(m_hWrite, buf, strlen(buf) + 1, &dwWrite, NULL))
{
AfxMessageBox(_T("write error child"));
}
//读取数据
char buf[128] = {0};
DWORD dwRead = 0;
ReadFile(m_hRead, buf, sizeof(buf), &dwRead, NULL );
//参考
http://www.cnblogs.com/BoyXiao/archive/2011/01/01/1923828.html
## 命名管道 ##
//服务端
//创建命名管
m_hPipe = CreateNamedPipe(_T("\\\\.\\pipe\\mypipe"), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, /*OVERLAPPED是为了满足异步实现非阻塞的工能,当连接上用事件通知*/
0, 1, 1024, 1024, 0, NULL);
if (m_hPipe == INVALID_HANDLE_VALUE)
{
return;
}
//创建事件
HANDLE hEvent;
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hEvent)
{
MessageBox(_T("创建事件对象失败!"));
CloseHandle(m_hPipe);
m_hPipe = NULL;
return;
}
OVERLAPPED ovlap;
ZeroMemory(&ovlap, sizeof(OVERLAPPED));
ovlap.hEvent = hEvent;
if (!ConnectNamedPipe(m_hPipe, &ovlap))
{
if (ERROR_IO_PENDING != GetLastError())
{
MessageBox(_T("等待客户连接失败!"));
CloseHandle(m_hPipe);
CloseHandle(hEvent);
m_hPipe = NULL;
return;
}
}
//重叠操作
if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE))
{
MessageBox(_T("等待对象失败!"));
CloseHandle(m_hPipe);
CloseHandle(hEvent);
m_hPipe = NULL;
return;
}
CloseHandle(hEvent);
//写数据
char buf[] = "this is named pipe server";
DWORD dwWrite = 0;
WriteFile(m_hPipe, buf, strlen(buf) + 1, &dwWrite, NULL);
//读数据
char buf[128] = {0};
DWORD dwRead = 0;
ReadFile(m_hPipe, buf, 128, &dwRead, NULL);
//客户端
//连接命名管道
if (!WaitNamedPipe(_T("\\\\.\\pipe\\mypipe"), NMPWAIT_WAIT_FOREVER))
{
return;
}
m_hPipe = CreateFile(_T("\\\\.\\pipe\\mypipe"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//写入数据
char buf[] = "this is named pipe client";
DWORD dwWrite = 0;
WriteFile(m_hPipe, buf, strlen(buf) + 1, &dwWrite, NULL);
//读取数据
char buf[128] = {0};
DWORD dwRead = 0;
ReadFile(m_hPipe, buf, 128, &dwRead, NULL);
//参考
//http://www.cnblogs.com/BoyXiao/archive/2011/01/02/1924188.html
## 邮槽 ##
//服务端
HANDLE hMail = CreateMailslot(_T("\\\\.\\mailslot\\myslot"), 424, MAILSLOT_WAIT_FOREVER, NULL);
if (hMail == INVALID_HANDLE_VALUE)
{
int nRes = GetLastError();
CString str;
str.Format(_T("%s"), nRes);
AfxMessageBox(str);
return;
}
char buf[424] = {0};
DWORD dwSize = 0;
ReadFile(hMail, buf, 424, &dwSize, NULL);
CString str;
str = buf;
MessageBox(str);
//客户端
HANDLE hMailslot;
hMailslot = CreateFile(_T("\\\\.\\mailslot\\myslot"), GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hMailslot)
{
MessageBox(_T("打开邮槽失败!"));
return;
}
char buf[] = "this is mail slot client";
DWORD dwSize = 0;
if (!WriteFile(hMailslot, buf, strlen(buf) + 1, &dwSize, NULL))
{
MessageBox(_T("写入邮槽失败!"));
}
//http://blog.csdn.net/kylin_p/article/details/5146797
//http://www.cnblogs.com/BoyXiao/archive/2010/12/31/1923462.html
//http://www.cnblogs.com/jzincnblogs/p/5192654.html
C++进程间通信的更多相关文章
- android:使用Messenger进行进程间通信(一)
Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...
- PHP 进程间通信——消息队列(msg_queue)
PHP 进程间通信--消息队列 本文不涉及PHP基础库安装.详细安装说明,请参考官网,或期待后续博客分享. 1.消息队列函数准备 <?php//生成一个消息队列的key$msg_key = ft ...
- WM_COPYDATA实现的不同进程间通信
进程间通信,通过SendMessage向另一进程发送WM_COPYDATA消息,实现不同进程间的消息通信. 需求:已写好一个工具软件,想在不更改当前的软件开发的前提下,实现为后面新开发的软件提供数据推 ...
- Linux学习笔记(12)-进程间通信|匿名管道
Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
- android:使用Messenger进行进程间通信(二)
//继续完善音乐播放器demo 相关文章: android:使用Messenger进行进程间通信(一):http://www.cnblogs.com/happyhacking/p/5318418.ht ...
- 进程间通信(linux)(转)
原帖发表在IBM的developerworks网站上,是一个系列的文章,作者郑彦兴,通过讲解和例子演示了Linux中几种IPC的使用方式,我觉得很好,在这里做一个保留,能看完的话Linux IPC的基 ...
- Linux进程间通信(一): 信号 signal()、sigaction()
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- Linux进程间通信(二):信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()
我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我 ...
随机推荐
- 用scikit-learn学习谱聚类
在谱聚类(spectral clustering)原理总结中,我们对谱聚类的原理做了总结.这里我们就对scikit-learn中谱聚类的使用做一个总结. 1. scikit-learn谱聚类概述 在s ...
- C#通过NPOI操作Excel
参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-post.html http://www.yuanjiaocheng.net/w ...
- [数据结构]——链表(list)、队列(queue)和栈(stack)
在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
- 【SAP业务模式】之ICS(六):发票输出类型
这篇开始主要讲述发票输出类型: 首先我们新建一个发票类型,用于公司间的发票MIV,而标准的发票类型还是F2保持不变: 一.新建发票类型: 目录:SPRO-销售与分销-出具发票-开票凭证-定义出具发票类 ...
- 15个C++项目列表
实验楼上有很多C++的实战项目,从简单到进阶,学习每个项目都可以掌握相应的知识点. 如果你还是C++新手的话,那么这个C++的项目列表你可以拿去练手实战开发,毕竟学编程动手实践是少不了的! 如果你不知 ...
- 利用PowerShell复制SQLServer账户的所有权限
问题 对于DBA或者其他运维人员来说授权一个账户的相同权限给另一个账户是一个很普通的任务.但是随着服务器.数据库.应用.使用人员地增加就变得很枯燥乏味又耗时费力的工作.那么有什么容易的办法来实现这个任 ...
- Oracle创建表空间
1.创建表空间 导出Oracle数据的指令:/orcl file=C:\jds.dmp owner=jds 导入Oracle数据的指令:imp zcl:/orcl file=C:\jds.dmp fu ...
- 一步步学习javascript基础篇(7):BOM和DOM
一.什么是BOM.什么是DOM BOM即浏览器对象模型,主要用了访问一些和网页无关的浏览器功能.如:window.location.navigator.screen.history等对象. DOM即文 ...
- Asp.Net 5 新增公告仓库
一直以来Asp.Net 5 都没有一个比较统一的公告页,对于一个在日夜更新的项目来说,很多人经常会遇到问题但是不知道去哪里寻找帮助,现在Asp.Net 5 项目组新增了一个公告仓库来解决这个问题. ...
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...