首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

异常

2012-03-09 
错误求救!看到一篇文章“VC++环境下利用管道和线程实现进程间通信”Copy里面的代码进行测试,代码如下:void C

错误求救!
看到一篇文章“VC++环境下利用管道和线程实现进程间通信”
Copy里面的代码进行测试,代码如下:

void CParentView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SECURITY_ATTRIBUTES sa;//安全性结构
PROCESS_INFORMATION pi;//子进程信息
STARTUPINFO startInfo; //子进程窗口属性结构
BOOL bTest;
HANDLE hPipeRead; //管道读句柄

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

//创建管道
bTest = CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0);
if (!bTest)
{
MessageBox(L"CreatePipe Failed !", NULL, MB_OK);
return;
}

//修改写句柄,使不被继承
bTest = DuplicateHandle(GetCurrentProcess(), hPipeWrite, GetCurrentProcess(),
NULL, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (!bTest)
{
MessageBox(L"Dup Handle Failed !");
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
return;
}

//填充进程启动信息
memset(&startInfo, 0, sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
startInfo.dwFlags = STARTF_USESTDHANDLES;
startInfo.hStdInput = hPipeRead;
startInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
startInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);

//创建子进程 Child
bTest = CreateProcess(NULL, L"Child.exe", NULL, NULL, TRUE, 0,
NULL, NULL, &startInfo, &pi);
if (!bTest)
{
MessageBox(L"CreateProcess Failed !");
CloseHandle(hPipeWrite);//删除管道
}
else
{
hProcess = pi.hProcess;
CloseHandle(pi.hProcess);
figure.nShape = ID_TEST_RECT;
SendCommand();
}

CloseHandle(hPipeRead);

CView::OnLButtonDown(nFlags, point);
}

但是每次这一句会出现错误
bTest = CreateProcess(NULL, L"Child.exe", NULL, NULL, TRUE, 0,
NULL, NULL, &startInfo, &pi);

错误信息提示 0xC0000005 写入位置 0x00424652 时发生位置访问冲突。

请大家帮忙看下哪里有错误?


[解决办法]
bTest = CreateProcess(NULL, L"Child.exe", NULL, NULL, TRUE, 0,
NULL, NULL, &startInfo, &pi); 

第2个参数不能是const的

详见windows核心编程5 进程

pszApplicationName和pszCommandLine参数分别指定新进程要使用的执行体文件的名称,以及要传给新进程的命令行字符串。先来谈谈pszCommandLine参数。
注意,pszCommandLine参数被原型化为一个PTSTR。这意味着CreateProces期望你传入的是一个非“常量字符串”的地址。在内部,CreateProcess实际上会修改你传给它的命令行字符串。但在CreateProcess返回之前,它会将这个字符串还原为原来的形式。
这是很重要的,因为如果命令行字符串包含在你的文件映像的只读部分,就会引起访问冲突(违例)。例如,以下代码就会导致冲突,因为Microsoft的C/C++编译器把"NOTEPAD"字符串放在只读内存中:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, TEXT("NOTEPAD"), NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
CreateProcess试图修改字符串时,会引起一个访问冲突(Microsoft C/C++编译器的早期版本把字符串放在可读/写内存中。所以对CreateProcess函数的调用不会引起访问冲突)。
解决这个问题的最佳方式是:在调用CreateProcess之前,把常量字符串复制到一个临时缓冲区,如下所示:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szCommandLine[] = TEXT("NOTEPAD");
CreateProcess(NULL, szCommandLine, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
[解决办法]
bTest = CreateProcess(NULL, L"Child.exe", NULL, NULL, TRUE, 0, 
NULL, NULL, &startInfo, &pi); 


为啥要加L??

试试:
bTest = CreateProcess(NULL, "Child.exe", NULL, NULL, TRUE, 0, 
NULL, NULL, &startInfo, &pi); 


看看Child.exe路径对不对!

热点排行