参考: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 未来的版本或许会对此进行修复。”
所以我们要做的就是避免采用这种方式传递字符串参数,取而代之的是使用数组方式。
原文链接: https://www.cnblogs.com/sunrisezhang/archive/2013/04/28/3050008.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/86419
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!