从函数返回动态 C 风格字符串?

发布于 2024-12-03 10:38:05 字数 682 浏览 0 评论 0原文

基本上我有一个大致如下所示的函数,我需要返回。

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);

Basically I have a function that roughly looks like this and I need to return out.

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];
}

Obviously out gets dereferenced when returning. What are my options? I need to be able to call this function like so. I would absolutely love to stay on the stack.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清音悠歌 2024-12-10 10:38:05

不要为任何此类担忧而烦恼,并返回 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< /code> 仅在调用 API 函数时提取 C 字符串。

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

Don't trouble yourself with any such worries and return an 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())
}

Then, in your C interface, use:

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

I would even make the argument of the function std::wstring and extract the C-string only when calling the API function.

The begin/end version includes all characters, the .data() version treats the buffer as a null-terminated string. Pick whichever is most appropriate.

旧人九事 2024-12-10 10:38:05

返回 std::string 将是我的第一选择。

但是,如果您确实需要 char*,您有多种选择。

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

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

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

Returning std::string would be my first choice.

However if you absolutely, positively need a char*, you have several options.

You could allocate a new char* on the heap and return that, being really, really careful to make sure that the caller always deallocates the memory. I believe there is a boost auto_ptr equivalent that is array friendly that would make explicit this ownership transfer.

Another option is for the caller to pass in the char* (and max size), and the function to put data in there. Thus the caller always owns the memory.

Another option is for the caller to pass in a char** (or char*&), and your function allocates memory to the caller's pointer. This makes the ownership transfer explicit. (you could also have a size (size_t&) parameter to hold the size, if it's something the caller is likely to need).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文