【2】进程间共享串口对象

在上位机开发过程中,控制软件往往会拥有一个通信串口与下位机进行数据通信,如果上位机需要添加一个小的功能模块,而此模块是以另一个进程出现,并且也通过相同的串口与下位机进行通信,这里就会出现串口共享的问题。下面我就利用内核对象复制的原理实现进程间串口的共享问题。

技术点分析:

  • 串口对象:串口对象属于Windows I/O对象中的一种,通过CreateFile函数进行创建,创建成功后会获取一个HANDEL句柄,数据的发送与接受采用WriteFile和ReadFile函数;
  • 跨进程边界的内核对象共享:内核对象的共享方式可以采用子进程继承、命名内核对象和内核对象复制。本工程中采用内核对象复制的方式实现,关键函数是DuplicateHandle;
  • 内核对象传递:在共享内核对象后,共享的内核对象已经在子进程的内核对象句柄表中进行了创建,但此时的内核对象还存在与主进程中,子进程并不知道此内核对象复制成功,所以需要采用进程间通信的方式将此内核对象传给子进程;本工程利用Windows消息机制进行传递,也可以采用相关的LPC方式,如:管道、邮槽等进程通信的方式传递;
  • 子进程创建:进程创建很简单,本工程中会有一个主进程MainProcess,通过一个按钮创建一个子进程SubProcess,采用的创建函数是CreateProcess。
API函数解析:
  • 用CreateFile创建一个串口对象,例如创建一个端口号1、波特率115200、数据位8、停止位1、校验位无的串口
    DCB dcb;  
  
    // Open Comm  
    HANDLE  m_hComm = CreateFile(L"COM1",  
                         GENERIC_READ | GENERIC_WRITE,  
                         0,  
                         NULL,  
                         OPEN_EXISTING,  
                         0,  
                         NULL);  
    if (m_hComm != INVALID_HANDLE_VALUE)  
    {  
        GetCommState(m_hComm,&dcb);  
        dcb.BaudRate = CBR_115200;  
        dcb.ByteSize = 8;  
        dcb.StopBits = ONESTOPBIT;  
        dcb.Parity = NOPARITY;  
        SetCommState(m_hComm,&dcb);  
    }  

  • 用WriteFile发送一串协议码
    if (m_hComm != INVALID_HANDLE_VALUE)  
    {  
        byte sendBuffer[8];  
        sendBuffer[0] = 0x80;  
        sendBuffer[1] = 0x94;  
        sendBuffer[2] = 0x06;  
        sendBuffer[3] = 0xff;  
        sendBuffer[4] = 0xff;  
        sendBuffer[5] = 0xff;  
        sendBuffer[6] = 0xff;  
        sendBuffer[7] = 0xff;  
  
        WriteFile(m_hComm,sendBuffer,8,NULL,NULL);  
    }  

  • 子进程创建,此处子进程执行文件名为SubProcess
    STARTUPINFO si = {sizeof(si)};  
    PROCESS_INFORMATION pi;  
    TCHAR subPath[] = L"SubProcess";  
    CreateProcess(NULL,subPath,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);  
  
    m_hSubProcess = pi.hProcess;  
    m_hMainProcess = GetCurrentProcess();

  • 内核对象跨进程共享
上述过程中,获取了子进程的进程句柄m_hSubProcess,和主进程的进程句柄m_hMainProcess,又得到了串口对象的句柄m_hComm,通过查阅MSDN关于DuplicateHandle的使用方法,如下:
BOOL DuplicateHandle(  
  HANDLE hSourceProcessHandle,  // handle to source process  
  HANDLE hSourceHandle,         // handle to duplicate  
  HANDLE hTargetProcessHandle,  // handle to target process  
  LPHANDLE lpTargetHandle,      // duplicate handle  
  DWORD dwDesiredAccess,        // requested access  
  BOOL bInheritHandle,          // handle inheritance option  
  DWORD dwOptions               // optional actions  
);  

现在就只需要一个接受的句柄m_hSubComm,就可以进行内核对象的复制了,代码如下:
    // Share Comm  
    BOOL bSuccess = DuplicateHandle(m_hMainProcess,m_hComm,m_hSubProcess,&m_hSubComm,  
        0,TRUE,DUPLICATE_SAME_ACCESS);  
  
    // Send Share Handle to SubProcess  
    if (bSuccess)  
    {  
        AfxMessageBox(_T("Success"));  
  
        HWND hWindow = ::FindWindow(NULL,_T("SubProcess"));  
        ::PostMessage(hWindow,UWM_COPYHANDLE,(WPARAM)m_hSubComm,0);  
    }  

  • 进程间内核对象传递
如上述代码所示,通过查找子进程的窗口句柄,然后发送自定义消息到子进程,就可以将句柄传递过去,这样子进程接收到消息后就可以利用传递过来的句柄进行串口操作了。

转载请注明出处,谢谢~~~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值