posts - 20,comments - 15,trackbacks - 0

错误使用api输入输出参数引起的问题

今天使用CRegKey::QueryBinaryValue碰到一个问题, 我是这样使用的,
// 遍历一个目录里的值
for(DWORD i=0; i<cValues; i++) {
 TCHAR achValue[10] = {0};
 DWORD cchValue = 10;
 DWORD dwRet = RegEnumValue(reg.m_hKey, i, achValue,
  &cchValue,
  NULL,
  NULL,    // &dwType,
  NULL,    // &bData,
  NULL);   // &bcData

 if(dwRet == ERROR_SUCCESS) {
  memset(buffer, 0, cbMaxValueData);
  DWORD len ;
  if(reg.QueryBinaryValue(achValue, buffer, &len) == ERROR_SUCCESS) {
  }
 }
}

当循环的第一次时能够取到数据, 而第二次时reg.QueryBinaryValue返回错误, 粗一看,
这是很费解的事, 为什么第一次能取到数据, 而第二次取不到, 仔细查看传入的3个参数,好像没什么问题,
buffer也足够大, 应该没有问题的, 观察返回的错误号是234, 错误解释是More data is available.
中文意思是更多的数据是可用的, 看这意思好像是len的问题, 如果是len的问题, 为什么第一次能成功而第二次失败了,
再次仔细观察len, 第一次len的值比第二次len的值要小, 这好像可以解释More data is available了,感觉应该len的问题了,
把msdn的RegQueryValueEx检索出来, 果然len那个参数是[in,out]属性,把 DWORD len ;改为DWORD len = cbMaxValueData; 后一切正常。

现在可以解释为什么第一次成功,而第二次失败了, len不赋值编译器应该给赋了一个随机值, 第二次初始化时编译器并没有清理
堆栈, 用的是第一次取得的值, 而第二次需要的len比第一次的大, 因此报234的错误。

总结上面的错误, 对于这种需要计算buffer长度的api, 最好给len附上buffer的长度丢入api, 这样基本上不会出错了。

这个问题竟然弄了一小时, 特此写下这篇小文加深印象。

posted on 2010-03-30 13:51 wangkang 阅读(453) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理