zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Flutter-动画-原理篇
    Flutter-动画-实践篇
    Flutter-动画-概念篇
    Android-textview图文混排(网络图片)
    Android--解决图片保存到相册显示1970年1月1日 8:00的问题
    Android--使用JobService实现进程保活
    Android--获取手机联系人和Sim卡联系人
    git 代码服务器的网页版gitweb的搭建
    Android 内存管理中的 Shallow heap Retained heap
    欧几里德算法----最大公约数算法
  • 原文地址:https://www.cnblogs.com/yhcao/p/6237618.html
Copyright © 2011-2022 走看看