我有一个获取std :: string的函数。该函数调用
第五个参数是注册表值的值,并且需要一个const BYTE *类型的变量。 所以我必须将std :: string转换为const BYTE *,并将结果数组的长度作为第6个参数。
我找到了一种方法,但感觉很难看,我真的不明白发生了什么。这是该功能的精简版:
void function(const std::string& newValue)
{
HKEY keyHandle;
if(RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("some key"),0,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
{
std::wstring wNewValue;
wNewValue.assign(newValue.begin(),newValue.end());
if (RegSetValueEx(keyHandle, TEXT("some value"), NULL, REG_SZ, (const BYTE*)(LPCTSTR)(wNewValue.c_str()), wNewValue.size()*2)==ERROR_SUCCESS)
{
//do something
}
RegCloseKey(keyHandle);
}
}
正如你所看到的,我首先创建一个宽字符串(UNICODE已定义),然后使用双重演员,并且对于长度我必须做* 2,否则它只会设置输入字符串的一半。
这种形式的演员是正常/最好的方式吗?
为什么* 2,会有什么更好的方法?
答案 0 :(得分:10)
void function(const std::string& newValue)
{
HKEY keyHandle;
if(RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("some key"),0,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
{
if (RegSetValueExA(keyHandle, "some value", NULL, REG_SZ, (const BYTE*)newValue.c_str(), newValue.size() + 1)==ERROR_SUCCESS)
{
//do something
}
RegCloseKey(keyHandle);
}
}
我删除了将字符串转换为wstring的部分,而不是显式使用ANSI版本的RegSetValueEx。
引用MSDN中的RegSetValueEx备注:
如果dwType是REG_SZ,REG_MULTI_SZ, 或REG_EXPAND_SZ类型和ANSI 使用此功能的版本 (通过明确地呼叫 RegSetValueExA或未定义 包含Windows.h之前的UNICODE 文件),指向的数据 lpData参数必须是ANSI 字符串。字符串是 之前转换为Unicode 存储在注册表中。
另请注意,cbData参数应包括空终止的大小。
答案 1 :(得分:3)
* 2是因为RegSetValueEx
想要知道要写入的字节数,而wstring中的每个字符(wchar_t)是两个字节宽。所以生成的字节数组大小是其两倍!
答案 2 :(得分:1)
不应该是wNewValue.size()*2+2
吗?空字符的+2?
MSDN说:lpData参数指向的信息大小,以字节为单位。如果数据类型为REG_SZ,REG_EXPAND_SZ或REG_MULTI_SZ,则cbData必须包含终止空字符或字符的大小。
答案 3 :(得分:1)
您也可以将unicode字符串复制到字节数组中:
LPWSTR pData = L"SampleGrabber";
int dwSize = wcslen(pData)*sizeof(TCHAR);
BYTE slump[256];
memset((void*) slump, 0, 256*sizeof(BYTE));
memcpy((void*) slump, (const void *) pData, dwSize*sizeof(BYTE));
globit = RegSetValueEx(hKey, NULL, 0, REG_SZ, (const BYTE*) slump, dwSize);
如果您不幸为WINCE 5.0设备编写代码而且它缺少部分regedit API。