C++ 根据mbsrtowcs实施mbsnrtowcs
在将libc++移植到Windows的几乎全部工作中,我需要函数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]
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++中没有<代码>限制< /代码>。根据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:我知道,我一直在看你与霍华德的讨论,顺便说一句,这是一份很棒的工作;)不过,我已经有太多的项目要做了:/