通过运行参数argv传递句柄

来源:互联网 发布:汽车电脑数据编程设备 编辑:程序博客网 时间:2024/06/06 00:19

开发过程中,有时候需要建立新的进程,但是windows进程间通信是比较麻烦的,如果使用命名管道等,有可能出现重名等问题,如果使用匿名管道,又有无法传递句柄的问题。

我们在一个项目开发中就遇到了这个问题,主要是有一个模块如果放在主程序中会显著拖慢程序的运行,但又需要它读出的数据。所以只好单独建立一个进程,然后把句柄和一些运行参数通过argv参数传给子进程。子进程采用命令行界面方式。

句柄值实际上定义为void*类型,我们直接将其作为整数转换成字符串,当句柄值大于0x80000000时,结果为负值。转换方式如下:


STARTUPINFO si; //一些必备参数设置 
memset(&si,0,sizeof(STARTUPINFO)); 
si.cb = sizeof(STARTUPINFO); 
si.dwFlags = STARTF_USESHOWWINDOW; 
si.wShowWindow = SW_SHOW; 
PROCESS_INFORMATION pi; //必备参数设置结束
CString commandLine;
commandLine.Format(L"InclinationReadProcess.exe %d %d %d",pClass->m_iComPort1No,pClass->m_iComPort2No,pClass->m_iReadingInterval);
CString str;
str.Format(L" %d %d %d",pClass->m_hWrite,pClass->m_hRead,hSelf);
commandLine += str;
DWORD dwCreateFlag;
#ifdef _DEBUG
dwCreateFlag = 0;
#else
dwCreateFlag = CREATE_NO_WINDOW;//如果是Release版本就不显示界面窗口
#endif
if(!CreateProcess(NULL,commandLine.GetBuffer(0),NULL,NULL,TRUE,dwCreateFlag,NULL,NULL,&si,&pi))
{
#ifdef SHOW_DIALOG
AfxMessageBox(L"创建进程失败!");
#endif // SHOW_DIALOG

CloseHandle(hSelf);
return 4;
}
else
{
pClass->m_hSubProcess = pi.hProcess;
pClass->m_hSubProcessThread = pi.hThread;
}



在子进程中检查传入的参数,然后使用_wtoi转换成整数,再转换成句柄值,即使是大于0x80000000也可以转换成功。


int portNo1,portNo2,postPeriod;
HANDLE hWrite = NULL,hRead = NULL,hParent = NULL;
if (argc < 7)
{
#ifdef _DEBUG
cout<<"argc should be 7!"<<endl;
Sleep(5000);
#endif
return 2;
}
else
{
try
{
portNo1 = _wtoi(argv[1]);
portNo2 = _wtoi(argv[2]);
postPeriod = _wtoi(argv[3]);
hWrite = (HANDLE)_wtoi(argv[4]);
hRead = (HANDLE)_wtoi(argv[5]);
hParent = (HANDLE)_wtoi(argv[6]);
}
catch(...)
{
#ifdef _DEBUG
cout<<"params convert failed!"<<endl;
Sleep(5000);
#endif
return 3;
}
}

0 0
原创粉丝点击