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

fumotvh3  于 2023-03-09  发布在  Windows
关注(0)|答案(4)|浏览(120)

许多windows API都有一个指向buffer的指针和一个size元素,但是结果需要转换成c++字符串(我在这里使用的是windows unicode,所以它们是wstring)
下面是一个例子:

#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,它只是一个方便的示例。

yzuktlbb

yzuktlbb1#

在本例中,我看不出std::vector会带来什么。MAX_COMPUTERNAME_LENGTH不太可能非常大,因此我将简单地使用C样式数组作为临时缓冲区。

nxagd54h

nxagd54h2#

请看另一个问题的答案。它提供了一个StringBuffer类的源代码,这个类可以非常干净地处理这种情况。

kr98yfug

kr98yfug3#

我要说的是,既然您已经在更通用的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对象。

eqoofvh9

eqoofvh94#

我会使用向量,作为对你说你选了一个糟糕例子的回应,假设我们没有一个合理的字符串长度的常量上限,那么事情就不那么简单了:

#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定义了非常量operator[]返回一个reference,并且它返回data()[pos]。所以如果reference只是一个普通的wchar_t&,那么就没有机会通过引用来实现令人兴奋的写入时复制行为。而且字符串实际上必须是可以通过指针&buffer[0]修改的。我认为。这里的基本问题是标准允许实现比原来需要的更多的灵活性。
这是一个很大的工作和注解,虽然只是为了避免复制字符串,所以我从来没有觉得需要避免一个中间数组/向量。

相关问题