CPP Windows 字符串转换混淆了 CStringA 和 LPCWSTR
CPP Windows string conversions confusion CStringA and LPCWSTR
我需要使用 WinAPI 函数重新启动 Windows 服务,我不熟悉C++中的字符串。
我的函数接收为参数:const CStringA& serviceName
:
bool MyClassName::RestartServer(const CStringA& serviceName)
当我通过OpenService(..)
获取SC句柄时,我需要提供类型LPCWSTR
:
SC_HANDLE SHandle = OpenService(hSCManager, LPCWSTR serviceNameAsWideString, SC_MANAGER_ALL_ACCESS);
如何将CStringA
转换为LPCWSTR
?
我试图遵循:
CA2W(serviceName, CP_UTF8);
CString str("MyServiceName"); CStringW strw(str); LPCWSTR ptr = strw;
两者都无法正常工作,它们进行了编译,但是当我尝试执行代码时。
它未能OpenService()
.
什么有效:
LPCWSTR newString = serviceName.AllocSysString();
我在这里错过了什么?为什么 1 和 2 不起作用?为什么 3 有效?
如何正确释放新字符串?
您的代码需要转换,因为您正在调用基于TCHAR
的OpenService()
宏,该宏映射到OpenServiceW()
或OpenServiceA()
,具体取决于是否定义了UNICODE
:
__checkReturn
WINADVAPI
SC_HANDLE
WINAPI
OpenServiceA(
__in SC_HANDLE hSCManager,
__in LPCSTR lpServiceName,
__in DWORD dwDesiredAccess
);
__checkReturn
WINADVAPI
SC_HANDLE
WINAPI
OpenServiceW(
__in SC_HANDLE hSCManager,
__in LPCWSTR lpServiceName,
__in DWORD dwDesiredAccess
);
#ifdef UNICODE
#define OpenService OpenServiceW
#else
#define OpenService OpenServiceA
#endif // !UNICODE
在您的情况下,UNICODE
在您的项目中明确定义,因此您的代码实际上是在调用OpenServiceW()
,这就是为什么它需要LPCWSTR
作为输入。
您的RestartServer()
方法将CStringA
(基于char
的 ANSI)字符串作为输入,因此您应该显式使用OpenServiceA()
来匹配相同的字符类型,无需转换:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenServiceA(hSCManager, serviceName, SC_MANAGER_ALL_ACCESS);
...
}
否则,如果要继续在代码1中使用基于TCHAR
的功能,则应将RestartServer()
方法更改为采用CString
而不是CStringA
,以便它采用与OpenService()
相同的 ANSI/Unicode 映射(以及其他基于TCHAR
的函数),再次避免转换:
1:你不应该这样做,因为现在很少需要为Win9x/ME编写代码。自NT4以来,Windows一直是基于Unicode的操作系统。
bool MyClassName::RestartServer(const CString& serviceName)
如果这不是您的选择,那么CA2W()
就可以正常工作:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
USES_CONVERSION;
...
SC_HANDLE SHandle = OpenService(hSCManager, ATL::CA2W(serviceName), SC_MANAGER_ALL_ACCESS);
...
}
不过,您可以考虑在内部仅使用CString
,并在需要时让它处理转换:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenService(hSCManager, CString(serviceName), SC_MANAGER_ALL_ACCESS);
...
}
或者,使代码具有条件:
bool MyClassName::RestartServer(const CStringA& serviceName)
{
...
SC_HANDLE SHandle = OpenService(hSCManager,
#ifdef UNICODE
CStringW(serviceName)
#else
serviceName
#endif
, SC_MANAGER_ALL_ACCESS);
...
}
CStringA
和CStringW
都有构造函数同时接受const char*
和const wchar_t*
C字符串。
写下以下内容:
CStringW serviceNameW( serviceName );
大约AllocSysString
,它在 BSTR 中创建一个副本,它们比 C 字符串更复杂,它们也是以 null 结尾的,但它们的长度也为负偏移量。如果要执行手动内存管理,请在指针上调用SysFreeString
。或者,如果需要 BSTR 但不需要手动内存管理,请使用CComBSTR
类。
- 使用 CStringW/CStringA 和 CT2W/CT2A 转换字符串有什么区别?
- C++ 在参数中将字符串转换为 LPCWSTR
- 'Cannot add two pointers'添加带有 WCHAR 的 LPCWSTR
- CPP Windows 字符串转换混淆了 CStringA 和 LPCWSTR
- 代码 c++ VS 2010 中的 LPCWSTR 到字符串转换问题
- 无法将常量字符 [16] 转换为 LPCWSTR
- LPCWSTR 查找和替换为转义字符
- 类型 "const char *" 的参数与类型 "LPCWSTR" 的参数不兼容
- 无法将参数 2 从 'const char [5]' 转换为 'LPCWSTR'
- 使用 std::文件系统输出作为 LPCWSTR
- 如何转换LPCWSTR和CHAR
- 将变量传递给WIN32 API LPCWSTR
- 将 LPCWSTR 字符串打印到文件
- 如何将 CStringW 转换为 LPCWSTR
- 如何比较strstr(lpcwstr,char*);
- 将SystemTime转换为LPCWSTR
- LPCWSTR 无法在 TextOut() 方法上正确转换
- 内存引用范围问题:变量值被重置,如何将值分配给LPCWSTR
- 将字符串解析为LPCWSTR
- 无法将'LPCWSTR {aka const wchar_t*}'转换为 'LPCSTR {aka const char*}