在将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 ++,所以也许const_cast
在这里几乎没有什么害处?我也可以访问c ++ 0X(libc ++是/需要一个c ++ 0x子集)。
编辑:Clang错误消息显示为:
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;
^
EDIT2:修复错误的问题。 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;
}
我添加了一个FIXME,说正确的方法是通过mbrtowc实现它。
答案 0 :(得分:4)
这里存在一个问题(与我认为的const
没有关系。)
mbsrtowcs
可能会将*src
设置为NULL
。
mbsnrtowcs
当然也应该这样做。
但是对你来说这会造成2个错误:
mbsrtowcs
将*src
设置为NULL
,则mbsnrtowcs
mbsnrtowcs
设置为nmcsrc
,则NULL
内存泄漏
或许只是咬紧牙关并以mbsnrtowcs
方式实施mbrtowc
会更有效率吗?
如果你需要同时实现这些(我猜你这样做),你也可以通过调用mbsrtowcs
来解决问题,并在mbsnrtowcs
方面实施strlen
一开始不失一般性(并避免复制)。
答案 1 :(得分:1)
没有问题,因为该函数需要更严格的接口。所以你可以抛出指针:
const size_t result = std::mbsrtowcs(dst, const_cast<const char **>(&nmcsrc), len, ps);
我不确定restrict
;你可能还需要将它添加到转换器中(不是在GCC上) - 这是编译器相关的问题,因为C ++中没有restrict
。