C++ 根据mbsrtowcs实施mbsnrtowcs

C++ 根据mbsrtowcs实施mbsnrtowcs,c++,C++,在将libc++移植到Windows的几乎全部工作中,我需要函数mbsnrtowcs,并且认为最简单的方法是用mbsrtowcs实现它: size_t mbsnrtowcs( wchar_t *__restrict__ dst, const char **__restrict__ src, size_t nmc, size_t len, mbstate_t *__restrict__ ps ) { char* nmcsrc = new char[nmc+1]

在将libc++移植到Windows的几乎全部工作中,我需要函数
mbsnrtowcs
,并且认为最简单的方法是用
mbsrtowcs
实现它:

size_t mbsnrtowcs( wchar_t *__restrict__ dst, const char **__restrict__ src,
               size_t nmc, size_t len, mbstate_t *__restrict__ ps )
{
    char* nmcsrc = new char[nmc+1];
    strncpy( nmcsrc, *src, nmc );
    nmcsrc[nmc] = '\0';
    const size_t result = mbsrtowcs( dst, &nmcsrc, len, ps );
    delete[] nmcsrc;
    return result;
}
这里的问题是,
mbsrtowcs
需要
&nmcsrc
类型为
const char**
,而不是,因为它是一个字符串,我刚刚将第一个
nmc
元素复制到其中,并在其中添加了
\0
字符。我怎样才能解决这个问题?严格说来,这是编译为C++的,所以也许<代码> COSTOSTCAST 不会有什么害处吗?我还可以访问c++0X(libc++是/需要一个子集c++0X)

编辑:叮当声错误消息显示:

M:\Development\Source\libc++\src\support\win32\support.cpp:37:27: error: no matching function for call to 'mbsrtowcs'
const size_t result = mbsrtowcs( dst, &nmcsrc, len, ps );
                      ^~~~~~~~~
M:/Development/mingw64/bin/../lib/clang/3.0/../../../x86_64-w64-mingw32/include\wchar.h:732:18: note: candidate function not viable: no known conversion from 'char **' to 'const char **restrict' for 2nd argument;
  size_t __cdecl mbsrtowcs(wchar_t * __restrict__ _Dest,const char ** __restrict__ _PSrc,size_t _Count,mbstate_t * __restrict__ _State) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
                 ^
编辑2:修复出了什么问题。Matthieu,我已经改变了我的天真实现,如下所示:

size_t mbsnrtowcs( wchar_t *__restrict__ dst, const char **__restrict__ src,
                   size_t nmc, size_t len, mbstate_t *__restrict__ ps )
{
    char* local_src = new char[nmc+1];
    char* nmcsrc = local_src;
    strncpy( nmcsrc, *src, nmc );
    nmcsrc[nmc] = '\0';
    const size_t result = mbsrtowcs( dst, const_cast<const char **>(&nmcsrc), len, ps );
    // propagate error
    if( nmcsrc == NULL )
        *src = NULL;
    delete[] local_src;
    return result;
}
size\t mbsnrtowcs(wchar\u t*\uuuuu restrict\uuuuu dst,const char**\uuu restrict\uuuu src,
尺寸(nmc、尺寸长度、mbstate*\uuuuuuuuuuuuuup)
{
char*local_src=新字符[nmc+1];
char*nmcsc=本地_src;
strncpy(nmcsrc,*src,nmc);
nmcsrc[nmc]='\0';
const size_t result=mbsrtowcs(dst、const_cast(&nmcsrc)、len、ps);
//传播错误
如果(nmcsrc==NULL)
*src=NULL;
删除[]本地\u src;
返回结果;
}
我还添加了一个FIXME,它说正确的方法是通过mbrtowc实现它。

这里有一个问题(我认为与
常量不太相关)

mbsrtowcs
可能会将
*src
设置为
NULL

mbsnrtowcs
当然也应该这样做

但是,对于您来说,它会导致两个错误:

  • 由于您创建了本地别名,因此如果
    mbsrtowcs
    *src
    设置为
    NULL
    ,则不会对
    mbsnrtowcs的调用者反映此别名
  • 如果
    nmcsrc
    设置为
    NULL
也许简单地咬紧牙关,在
mbrtowc
方面实现
mbsnrtowcs
会更有效率


如果您需要同时实现这两个功能(我想您是这样做的),您还可以在开始时调用
strlen
而不失去通用性(并避免复制),以
mbsnrtowcs
的形式实现
mbsrtowcs

没有问题,因为函数需要更严格的接口。因此,您可以直接投射指针:

const size_t result = std::mbsrtowcs(dst, const_cast<const char **>(&nmcsrc), len, ps);
const size\u t result=std::mbsrtowcs(dst、const\u cast(&nmcsrc)、len、ps);

我不确定是否要限制
;您可能需要将其添加到CAST(而不是GCC),但是,这是一个编译器依赖的问题,因为C++中没有<代码>限制< /代码>。

根据 man MbSrRoScs<代码>,该函数的签名是“代码>(WCHAR *、const char *、sisixt、MbStesteT**)< /C>。那里没有
const wchar\u t**
。凯瑞克:这就是我的意思。我还需要
wchar\u t
版本,因此需要输入错误。修正了问题中的问题。但是没有问题,是吗?你只是想要更稳定的东西。克伦:克朗认为有。请注意,这些函数是用
restrict
关键字声明的……在C++11(或任何C++)中都没有
restrict
。您最多只能处理编译器扩展。例如,好的观点;实际上,您需要正确地实现函数逻辑。复制一份
nmsrc
将是一个开始。@Kerrek:是的,先更正,然后快速复制。保存
nmsrc
以确保
删除所分配的缓冲区,并能够检查其是否已设置为
NULL
将起作用。在相关的注释中,我仍然没有发现为什么C++不允许<代码> const < /Cord>演绎。我认为Johannes提供了一个演示,演示了这是如何被滥用的,但我不确定:/我理解我的实现是幼稚和糟糕的,但我真的不相信自己会在这些事情上做其他事情。libc++是开源的,所以如果你觉得有必要;)?我已经用空处理更新了我的问题。我想现在一切都好了吧?我希望我没有弄糟指针别名…@MatthieuM:不知道这是否是一个理想的扩展,但目前你正试图从
t*
中推断
U*
,这是不允许的-你只能从
t
中推断
const t
@rubenvb:我知道,我一直在看你与霍华德的讨论,顺便说一句,这是一份很棒的工作;)不过,我已经有太多的项目要做了:/