混合c ++标准字符串和windows API

时间:2010-03-13 10:07:09

标签: c++ windows

许多Windows API采用指向缓冲区和大小元素的指针,但结果需要进入c ++字符串。 (我在这里使用windows unicode,所以它们是wstrings)

以下是一个例子: -

#include <iostream>
#include <string>
#include <vector>
#include <windows.h>

using namespace std;

// This is the method I'm interested in improving ...
wstring getComputerName()
{
    vector<wchar_t> buffer;
    buffer.resize(MAX_COMPUTERNAME_LENGTH+1);
    DWORD size = MAX_COMPUTERNAME_LENGTH;

    GetComputerNameW(&buffer[0], &size);

    return wstring(&buffer[0], size);
}

int main()
{
    wcout << getComputerName() << "\n";
}

我的问题是,这是编写getComputerName函数的最佳方法,以便更好地适应C ++,还是有更好的方法?除非我错过了什么,否则我没有看到任何方式直接使用字符串而不通过向量?它工作正常,但不知何故看起来有点难看。问题不在于特定的API,它只是一个方便的例子。

4 个答案:

答案 0 :(得分:7)

在这种情况下,我没有看到std :: vector为派对带来了什么。 MAX_COMPUTERNAME_LENGTH可能不是很大,所以我只想使用C风格的数组作为临时缓冲区。

答案 1 :(得分:3)

请参阅this answer其他问题。它为StringBuffer类提供了源代码,它可以非常干净地处理这种情况。

答案 2 :(得分:2)

我想说,既然你已经完成了在更通用的C ++接口背后提取Windows API的任务,那就完全废除了vector,并且不要为wstring构造函数而烦恼:

wstring getComputerName()
{
    wchar_t name[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD size = MAX_COMPUTERNAME_LENGTH;

    GetComputerNameW(name, &size);

    return name;
}

此函数将返回有效的wstring对象。

答案 3 :(得分:1)

我会使用矢量。在回答你说你选择了一个不好的例子时,假装我们在字符串长度上没有合理的恒定上限。然后它就不那么容易了:

#include <string>
#include <vector>
#include <windows.h>

using std::wstring;
using std::vector;

wstring getComputerName()
{
    DWORD size = 1; // or a bigger number if you like
    vector<wchar_t> buffer(size);
    while ((GetComputerNameW(&buffer[0], &size) == 0))
    {
        if (GetLastError() != ERROR_BUFFER_OVERFLOW) aargh(); // handle error
        buffer.resize(++size);
    };
    return wstring(&buffer[0], size);
}

在实践中,你可能可以通过写入字符串来逃避,但我并不完全确定。除了标准中的内容之外,你当然还需要std::wstring实现的额外保证,但我希望MSVC的字符串可能正常。

我认为,如果wstring::referencewchar_t&,那么您就会排序。 21.3.4定义非const operator[]返回reference,并返回data()[pos]。因此,如果reference只是一个普通的wchar_t&,那么通过引用就没有令人兴奋的写时复制行为的范围,并且字符串实际上必须可以通过指针&buffer[0]进行修改。我认为。这里的基本问题是标准允许实现更灵活,而不是需要它。

虽然这是很多努力和评论,只是为了避免复制字符串,所以我从来没有觉得需要避免使用中间数组/向量。