2

基本上我有一个大致看起来像这样的函数,我需要返回。

const char* UTF16ToUTF8(const wchar_t *in) {
    int tmp = wcslen(in);
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &in[0], (size_t)tmp, NULL, 0, NULL, NULL);
    std::vector<char> out;
    out.resize(size_needed);
    WideCharToMultiByte(CP_UTF8, 0,  &in[0], (size_t)tmp, &out[0], size_needed, NULL, NULL);

    return &out[0];
}

显然,在返回时 out 会被取消引用。我有哪些选择?我需要能够像这样调用这个函数。我绝对愿意留在堆栈上。

utf8outputfile << UTF16ToUTF8(wchar_tString) << endl;
fprintf(utf8outputfile, "%s", UTF16ToUTF8(L"Mmm Mmm Unicode String κόσμε"));
return UTF16ToUTF8(wchar_tString);
4

2 回答 2

6

不要为任何此类担忧而烦恼并返回std::string

std::string UTF16ToUTF8(const wchar_t *in) {
  std::vector<char> out;
  //...
  return std::string(out.begin(), out.end());  // or std::string(out.data())
}

然后,在您的 C 接口中,使用:

printf("%s", UTF16ToUTF8(ws).c_str());

我什至会std::wstring在调用 API 函数时设置函数的参数并提取 C 字符串。

begin/end版本包括所有字符,该.data()版本将缓冲区视为以空字符结尾的字符串。选择最合适的。

于 2011-09-05T02:18:39.697 回答
2

返回 std::string 将是我的首选。

但是,如果您绝对肯定需要一个 char*,您有多种选择。

您可以在堆上分配一个新的 char* 并返回它,非常非常小心地确保调用者总是释放内存。我相信有一个对数组友好的 boost auto_ptr 等效项,可以明确地进行所有权转移。

另一种选择是让调用者传入 char* (和最大大小),以及将数据放入其中的函数。因此,调用者始终拥有内存。

另一种选择是让调用者传入一个 char**(或 char*&),然后您的函数将内存分配给调用者的指针。这使得所有权转移明确。(如果调用者可能需要它,您也可以有一个大小 (size_t&) 参数来保存大小)。

于 2011-09-05T05:26:12.563 回答