我有一个函数,得到一个std ::string。 该函数调用
函数RegSetValueEx
第五个参数是registry值的值,并且需要const BYTE *types的variables。 所以我必须将std :: string转换为const BYTE *,并将结果数组的长度作为第6个参数。
我已经find了一个方法来做到这一点,但它感觉很难看,我真的不明白是怎么回事。 这是一个减肥版本的function:
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); } }
正如你所看到的,我首先做一个宽string(UNICODE被定义),然后使用双重强制转换,并且长度必须做* 2,否则它只会设置inputstring的一半。
这种forms是否正常/最好的方式来做到这一点?
为什么* 2,有什么更好的办法?
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); } }
我删除了将字符串转换为字符串的部分,而不是显式使用ANSI版本的RegSetValueEx。
来自RegSetValueEx在MSDN中的评论:
如果dwType是REG_SZ,REG_MULTI_SZ或REG_EXPAND_SZ类型,则使用此函数的ANSI版本(通过显式调用RegSetValueExA或在包含Windows.h文件之前未定义UNICODE),lpData参数指向的数据必须是一个ANSI字符串。 该字符串在存储在注册表中之前被转换为Unicode。
还要注意,cbData参数应该包含空终止的大小。
* 2是因为RegSetValueEx
想要知道要写入的字节数,并且每个字符(wchar_t)在一个wstring中是两个字节宽。 所以得到的字节数组有两倍的大小!
不应该是wNewValue.size()*2+2
吗? 空字符的+2? MSDN说:由lpData参数指向的信息的大小,以字节为单位。 如果数据类型为REG_SZ,REG_EXPAND_SZ或REG_MULTI_SZ,则cbData必须包含终止空字符的大小。
您也可以将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。