函数返回std::wstring = NULL;

Function returns std::wstring = NULL;

本文关键字:NULL wstring std 函数 返回      更新时间:2023-10-16

我试图为winapi函数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");    
}

作为异常的另一种选择,您还可以在参数列表中通过引用返回字符串,并通过返回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();
}

另一个解决方案(不抛出异常):使用Boost。可选库。

NULL绝对是 ok的,对于字符串,你特别不允许将空指针传递给字符串构造函数。

如果不想抛出异常,可以返回空字符串return std::wstring();

WinApi的设计,使它永远不会抛出异常。为了获得某些函数返回失败的原因,在大多数情况下,您必须通过GetLastError()获得最后一个错误。正如我所理解的,你的功能将是WinApi的一些补充,这将是易于使用的。所以我建议保留他们的设计。即,在失败的情况下,返回空字符串,并检查什么是最后的错误,如果你的函数返回它。

首先,GetWindowText()不返回HRESULT,所以你的代码在这方面是错误的。

第二,如果OK, 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;在这种情况下,您可能想要扩展经典的Fallible习语,以便它可以包含有关错误原因的附加信息。仍然另一种可能是通过输出参数返回值,并使用返回码(同样,可能带有附加的信息,并可能添加代码以确保它具有