我用C写的两个函数,都应该读从Windows注册表中的一些信息。虽然两者使用相同的逻辑,他们中的一个将引发错误。该工程的功能得到了一些CPU的信息。
struct CPUInfo {
wchar_t model[128];
DWORD frequency;
};
struct CPUInfo cpuinfo() {
SYSTEM_INFO siSysInfo;
HKEY hKey;
struct CPUInfo cpu = { L"", 0 };
LONG lRes = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0,
KEY_READ,
&hKey
);
if (lRes == ERROR_SUCCESS) {
DWORD dwBufferSize = sizeof(cpu.model);
ULONG nError = RegQueryValueExW(
hKey,
L"ProcessorNameString",
0,
NULL,
(LPBYTE)cpu.model,
&dwBufferSize
);
dwBufferSize = sizeof(DWORD);
nError = RegQueryValueExW(
hKey,
L"~MHz",
0,
NULL,
(LPBYTE)(&cpu.frequency),
&dwBufferSize
);
RegCloseKey(hKey);
}
return cpu;
}
这functios工程和信息是从注册表中检索。现在,我做同样的第二次使用此功能
struct GPUInfo {
DWORD adaptersCount;
};
struct GPUInfo gpuinfo() {
HKEY hKey;
struct GPUInfo gpu = { 0 };
LONG lRes = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"HARDWARE\\DEVICEMAP\\VIDEO",
0,
KEY_READ,
&hKey
);
if (lRes == ERROR_SUCCESS) {
DWORD dwBufferSize = sizeof(DWORD);
ULONG nError = RegQueryValueExW(
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
dwBufferSize
);
RegCloseKey(hKey);
}
return gpu;
}
当我调试程序,就像我说的,第一个函数的工作,但第二个抛出在这一点例外:
ULONG nError = RegQueryValueExW( // !!!! Access violation reading location 0x0000000000000004
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
dwBufferSize
);
我在注册表中检查和路径确实存在。真不明白,为什么第一个作品,但第二个没有。我打电话给他们上层出不穷
注意你的编译器警告。你的价值,而不是由地址传递lpcbData
(缓冲区长度)。
它应该是这样的:
DWORD dwBufferSize = sizeof(gpu.adaptersCount); // (2)
ULONG nError = RegQueryValueExW(
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
&dwBufferSize // (1)
);
变化:
dwBufferSize
面前,就像你的第一个例子sizeof
实际结构成员。这是未来的变化的脸相当,但更安全。参考: - RegQueryValueExW