C++ 函数返回std::wstring=NULL;
我正在尝试为winapi函数制作包装器C++ 函数返回std::wstring=NULL;,c++,exception-handling,error-handling,C++,Exception Handling,Error Handling,我正在尝试为winapi函数制作包装器GetWindowText。 函数返回std::wstring,但我不知道如何处理错误发生的位置。我返回NULL,但我知道这是错误的 std::wstring GetWindowText(HWND handle) { const int size = 1024; TCHAR wnd_text[size] = {0}; HRESULT hr = ::GetWindowText(handle, w
GetWindowText
。
函数返回std::wstring,但我不知道如何处理错误发生的位置。我返回NULL,但我知道这是错误的
std::wstring GetWindowText(HWND handle)
{
const int size = 1024;
TCHAR wnd_text[size] = {0};
HRESULT hr = ::GetWindowText(handle,
wnd_text, size);
if(SUCCEEDED(hr))
return std::wstring(wnd_text);
else
return NULL;
}
扔一个硬币代替
std::wstring GetWindowText(HWND handle)
{
const int size = 1024;
TCHAR wnd_text[size] = {0};
HRESULT hr = ::GetWindowText(handle,
wnd_text, size);
if(SUCCEEDED(hr))
return std::wstring(wnd_text);
else
throw std::runtime_error("insert error message here");
}
NULL肯定是不确定的。对于字符串,特别不允许向字符串构造函数传递NULL指针
如果不想抛出异常,可以返回空字符串,
return std::wstring()代码>作为异常的替代方法,您还可以通过在参数列表中引用返回字符串,并通过返回true或false指示成功,即
bool GetWindowText(HWND handle, std::wstring& windowText)
{
const int size = 1024;
TCHAR wnd_text[size] = {0};
HRESULT hr = ::GetWindowText(handle,
wnd_text, size);
if(SUCCEEDED(hr))
{
windowText = wnd_text;
return true;
}
else
return false;
}
另一种避免引用参数的方法是返回一个类的实例,该类封装了一个值,但也让您知道是否存在一个值,例如
class ValueWrapper
{
public:
ValueWrapper() : present( false ) {}
ValueWrapper( const std::wstring& s ) : value( s ), present( true ) {}
bool isPresent() const { return present; }
const std::wstring& getValue() const { return value; }
private:
std::wstring value;
bool present;
};
请注意,您可以非常轻松地为这个包装器设置模板。你的功能就是
ValueWrapper GetWindowText(HWND handle)
{
const int size = 1024;
TCHAR wnd_text[size] = {0};
HRESULT hr = ::GetWindowText(handle,
wnd_text, size);
if(SUCCEEDED(hr))
return ValueWrapper( wnd_text );
else
return ValueWrapper();
}
WinApi的设计使其永远不会引发异常。要想知道某个函数返回失败的原因,在大多数情况下,您必须通过获取最后一个错误。据我所知,您的函数将是WinApi的一个补充,它将易于使用。所以我建议保留他们的设计。i、 e.如果失败,返回空字符串,如果函数返回,则检查最后一个错误是什么 另一种解决方案(不引发异常):使用库。首先,GetWindowText()不返回HRESULT,因此您的代码在这方面是错误的
第二,如果确定,GetWindowTextW在任何错误或字符数上返回0。
所以只需返回一个空字符串:
std::wstring GetWindowText(HWND handle)
{
const int size = 1024;
TCHAR wnd_text[size] = {0};
INT n = ::GetWindowTextW(handle,
wnd_text, size);
if(n > 0)
return std::wstring(wnd_text,n);
else
return std::wstring();
}
根据您的应用程序,有几种合适的
解决。第一种是在发生异常时抛出异常
错误:如果执行此路线,则应定义WindowsError
异常(源自标准异常之一),其中
包括GetLastError
中提供的所有信息,
以及可能的附加信息(用于
失败等),以易于解析的格式。二是
返回某种类型的易出错的;在这种情况下,您可能需要
扩展经典的Fallible
习惯用法,使其能够包含
有关错误原因的其他信息。仍然
另一种可能是通过out参数返回值,
并使用返回码(同样,可能带有额外的
信息,并可能添加代码以确保
在被破坏之前已经测试过了。)不要认为这是个好主意。通常winapi函数不会引发异常。最好是通过<代码> SETLASTRATROR()/< > Mihran >:设置为C++包装器,因此在C++习语中转换WiAPI的成语是正确的。如果它将GetLastError
值封装在一个特定的异常类型中会更好。在这种情况下,他仍然必须返回一个值。它应该有什么价值?此外,每次调用此函数后调用GetLastError
,比捕获异常要难看得多。我会计算代码以从故障代码生成错误消息,但在响应错误情况时抛出异常是完全正确的(假设不是操作系统接口本身在执行此操作;操作系统本身不抛出异常有一些很好的理由)。但如果所讨论的字符串实际上是空的,它将导致一个假错误。@Grigory-可能是的,这取决于接口的定义。但是,std::wstring(NULL)始终是一个错误,因为它违反了语言标准!请注意,这是ValueWrapper
@ildjarn:谢谢。我不知道。请注意,boost::optional
的一个名称在本例中有误导性——这里的常规名称是易出错的。(此外,还可以扩展一个易出错的
,以便它包含有关错误的附加信息。)