[英]CPP Windows string conversions confusion CStringA and LPCWSTR
我需要使用WinAPI函数来重新启动Windows服务,我对C ++中的字符串不熟悉。
我的函数接收作为参数: const CStringA& serviceName
:
bool MyClassName::RestartServer(const CStringA& serviceName)
当我通过OpenService(..)
获得SC Handle时,我需要提供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有效?
如何正确地释放newString?
您的代码需要进行转换,因为您正在调用基于TCHAR
的OpenService()
宏,该宏根据是否定义UNICODE
映射到OpenServiceW()
或OpenServiceA()
:
__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字符串的构造const char*
。
写以下内容:
CStringW serviceNameW( serviceName );
关于AllocSysString
,它在BSTR中创建一个副本,它们比C字符串复杂,它们也以null终止,但是它们的长度也为负偏移量。 如果要执行手动内存管理,请在指针上调用SysFreeString
。 或者,如果您需要BSTR但不希望手动进行内存管理,请使用CComBSTR
类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.