【问题标题】:behavior different when run outside of visual studio在 Visual Studio 之外运行时行为不同
【发布时间】:2014-07-21 07:18:57
【问题描述】:

我对以下代码的行为感到惊讶:

if(RegQueryValueEx(....)!=ERROR_SUCCESS){
...
}

当它从 Visual Studio 运行时,它没有进入这个 if 块,因为密钥确实存在。当在 Visual Studio 环境之外运行时,它评估为 true 并因此进入块,即使查询的密钥存在。经过一些测试,我发现当我第一次将它保存到一个变量时,它总是运行良好。使用以下代码:

HKEY hSoftwareKey,hAppKey;
DWORD dwLength;
int iStatus=1;
char szBuffer[MAX_PATH];
if(iStatus&&RegOpenKeyA(HKEY_CURRENT_USER,"Software",&hSoftwareKey)!=ERROR_SUCCESS)
    iStatus = 0;
if(iStatus&&RegCreateKeyA(hSoftwareKey,"Amine",&hAppKey)!=ERROR_SUCCESS){
    iStatus = 0;
}

ZeroMemory(szBuffer,MAX_PATH);
LONG lRet;
lRet = RegQueryValueExA(hAppKey,"One",0,0,reinterpret_cast<LPBYTE>(szBuffer),&dwLength);

这种行为是否与 __stdcall/WINAPI 调用约定有关?如果是这样,请有人解释原因

【问题讨论】:

  • 在这两种情况下,您是否使用相同的使用权限提升来执行此操作?你得到什么 lRet
  • 同一海拔。 lRet 是 ERROR_SUCCESS。有趣的是我必须先存储返回值,但我不能直接在 if 块中比较它
  • 您是否在 Visual Studio 内部和外部运行相同的(调试)构建 exe?请编辑问题并将所有参数提供给RegQueryValueEx() 调用
  • 它是完全相同的文件。确定我会输入参数
  • @thebaconing 请不要修复问题中的代码,否则答案没有意义,未来的读者将无法理解问题的原因。

标签: visual-studio-2010 winapi stack calling-convention


【解决方案1】:

在调用RegQueryValueEx()之前需要将dwLength初始化为MAX_PATH,否则它的值是不确定的。

来自MSDN RegQueryValueEx

lpcbData 是一个指向变量的指针,该变量指定由 lpData 参数指向的缓冲区的大小,以字节为单位。当函数返回时,此变量包含复制到 lpData 的数据的大小

【讨论】:

  • 嗯,你是对的(我自己刚刚阅读了这篇文章),但即使我没有这样做,它仍然有效。那可能是因为这个参数是可选的
  • 只有lpData为NULL时才可选
  • 确实奇怪的返回行为是由于未初始化 dwLength 造成的。谢谢
  • 如果 dwLength 在 Visual Studio 下被初始化为 0xCCCCCCCC,我不会感到惊讶,但在外部运行时却是随机的。见techbase.kde.org/Development/Tutorials/Debugging/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多