关于创建进程函数CreateProcess()字符串参数的说明
参考:http://blog.csdn.net/a32132100/article/details/6412386
void main() { STARTUPINFO si = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION pi; TCHAR szCmd[] = TEXT("cmd"); //LPWSTR szCmd = L"cmd";// 会导致运行时问题 //WCHAR szCmd[] = L"cmd";// 正确 // LPWSTR szCmd = new WCHAR[4]; // szCmd[0] = 'c'; // szCmd[1] = 'm'; // szCmd[2] = 'd'; // szCmd[3] = '\0'; //正确 //进行以下测试时请将 //STARTUPINFO si = { sizeof(STARTUPINFO) }; 改为 //STARTUPINFOA si = { sizeof(STARTUPINFOA) }; //且创建进程函数 CreateProcess 改为 CreateProcessA //LPSTR szCmd = "cmd"; //正确 //LPCSTR szCmd = "cmd"; //错误,CreateProcessA 参数2类型为 LPSTR,编译不通过 si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = true; BOOL bResult = CreateProcess( NULL, szCmd, NULL, NULL, FALSE, //CREATE_NEW_CONSOLE, CREATE_SUSPENDED, NULL, NULL, &si, &pi ); if (bResult) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } }
总结:对于参数2来说
1.首先它不支持const参数传递。
2.对于char和wchar_t型数组来说总是可以的,他们都是位于栈上的局部可修改的内存。(这也是参数的要求)
3.对于使用“一个指针指向“字符串字面值”作为参数的情况,在ANSI版本CreateProcessA()下是可以正常运行的,而Unicode下的CreateProcessW()无法正常运行
原因:
CreateProcessW()中的字符串参数之所以要求是非const,是因为函数在内部执行过程中对字符串参数进行了修改(在函数返回前,这个字符串会被还原为原来的形式)。
而采用一个“可读写指针”指向“字符串字面值常量”作为参数,虽然编译可以通过,但是实际上我们是不能对“字符串字面值”进行修改的,如:
char* multiChar = "multichar"; wchar_t* wideChar = "widechar";
编译器识别类型时将它们认作非const形式,但是实际上任何对它们内容的修改,都会导致访问冲突。
那么,为CreateProcessA()传递这种参数为什么能正常运行呢?
CreateProcessA()的执行过程,是在内部将ANSI字符转存到一个Unicode字符数组副本中去,然后直接调用它的Unicode版本CreateProcessW(),其中没有对参数直接做修改,
所有操作都是由参数转存的Unicode副本完成的。而Unicode副本在函数内部是新在堆上分配的内存(参考《Windows via C/C++》2.8.1节的例子)
作者原话:(4.2.1节)
“目前,Microsoft 最应该做的一件事,就是修正 CreateProcess,使它自己能创建字符串的一个临时副本,从而使我们得到解放。Windows 未来的版本或许会对此进行修复。”
所以我们要做的就是避免采用这种方式传递字符串参数,取而代之的是使用数组方式。
posted on 2013-04-28 20:09 QQ_Sprite 阅读(1413) 评论(0) 编辑 收藏 举报