0

我试图从注册表中获取我所有的报告。不幸的是,我总是收到 ERROR_MORE_DATA 错误...我已经尝试让我的缓冲区更大,但它根本无济于事。这是我的代码:

DWORD registry::regGetValue(char *key, int index)
{
HKEY hKey; 
 RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
     DWORD chars = sizeof(key);
     LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
 RegCloseKey(hKey);
 return result;
}

参数是:

char key[512];
int index = 0;
4

2 回答 2

2

缓冲区可能足够大,您只是对函数的实际大小撒谎。

当您sizeof在指针上使用运算符时,它返回指针的大小,而不是它指向的数组的大小。并且因为key作为 a 传递给函数char*,所以它只是指向数组的指针,而不是数组本身。

您必须将缓冲区的实际大小作为参数与指针一起传递给函数:

DWORD regGetValue(char *key, size_t length, int index)
{
   HKEY hKey; 
   RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
   DWORD chars = length;
   LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
   RegCloseKey(hKey);
   return result;
}
char key[512];
int index = 0;
regGetValue(key, sizeof(key), index);

运算符在sizeof这里按预期工作,因为它在数组本身上进行操作,而不仅仅是指向它的指针。这种方法虽然在 C API 中很常见,但很麻烦。

您可以通过使用自动推断缓冲区大小并将其传递给实际完成工作的内部辅助函数的函数模板来稍微简化调用站点的事情:

// Helper function, implemented as a private member of your class
DWORD regGetValue(char *key, size_t length int index)
{
   HKEY hKey; 
   RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
   DWORD chars = length;
   LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
   RegCloseKey(hKey);
   return result;
}

// The public function that you will actually call
template <size_t N>
DWORD regGetValue(char (&key)[N], int index)
{
   return regGetValue(key, N, index);
}
char key[512];
int index = 0;
regGetValue(key, index);  // length determined and passed automatically

这是有效的,因为您传递了对数组的引用,而不是指针。

除了所有这些,我还必须认真质疑您为什么要调用 ANSI 函数并使用char*字符串。所有现代 Windows 应用程序都应该是 Unicode。这意味着调用W- 后缀版本的 Windows API 函数并wchar_t*用作您的字符串类型。确保为您的项目定义了UNICODE_UNICODE符号,如果使用错误的类型,您将收到编译时错误。

于 2013-07-25T13:53:28.290 回答
0

MSDN 说:如果 lpName 缓冲区太小而无法接收密钥的名称,则该函数返回 ERROR_MORE_DATA。在调用之前RegEnumKeyEx,您可以调用函数RegQueryInfoKey来确定由 标识的键的最大子键的大小hKey。的用法RegQueryInfoKey可以在这里找到:“ http://msdn.microsoft.com/en-us/library/windows/desktop/ms724902(v=vs.85).aspx

于 2013-07-25T13:51:27.740 回答