【问题标题】:iconv() 32 bit vs 64 bit on LinuxLinux 上的 iconv() 32 位与 64 位
【发布时间】:2013-05-19 12:03:49
【问题描述】:

我有一些代码在 Linux 上使用 iconv() 来验证字符串是否为 UTF-8 编码。我创建的转换如下:

iconv_t c = iconv_open("UTF-8","UTF-8");

我像这样运行 iconv():

int status = iconv(c, &fromArray, (size_t*)&inSize, &toArray, (size_t*)&outSize);

然后,如果 status 不是 -1,我将字符串设为有效的 UTF-8。

这可以在 32 位环境(最初开发和测试的环境)中编译并正常工作。但是我现在需要让它在 64 位环境中工作(具体来说,我相信 Fedora 14 的 64 位版本)。当我对此进行编译并运行测试时,status 始终是 -1,并且我总是在 errno 中得到一个 EILSEQ 错误,即使对于 32 位编译所说的相同字符串也可以。

有没有人知道为什么会发生这种情况?

【问题讨论】:

  • 虽然这可能不是问题,但inSizeoutSize 是什么?我问的原因是,如果类型与size_t 的大小不同,将它们转换为(size_t *) 可能会导致问题。
  • 确实,这就是问题所在。他们原本应该是ints,而本来应该是size_ts。更改类型停止了崩溃。当然,在我编写此代码时,执行此操作的代码现已失效,但我想为后代确认这一点。 :)

标签: c++ linux utf-8 iconv


【解决方案1】:

最近遇到了同样的问题。转换为 (size_t*) 更(非常)可能是根本原因。 这个问题甚至可以用下一个代码轻松模拟:

cat >Makefile <<EOF
all: build test clean

clean:
    rm -f *.o core* t32 t64
test: build
    @echo ; echo "run_32bit version:" ; ./t32
    @echo ; echo "run_64bit version:" ; ./t64
build:
    g++ -m32 t.cpp -o t32 -Wall -O0 -g
    g++      t.cpp -o t64 -Wall -O0 -g
EOF

cat >t.cpp <<EOF
#include <errno.h>
#include <stdio.h>
#include <iconv.h>

char buff_toArray [BUFSIZ];
char buff_fromArray [] = \
"<TESTS_STRINGS>\
    <T_VERIFICATION_STRINGS/>\
</TESTS_STRINGS>";

void iconv_test ( const char* desc, size_t* size )
{
   printf ("%s = size[%zu]\n",desc, (*size) );
}

int main (int argc, char* argv[])
{

 char* toArray = &buff_toArray[0];
 char* fromArray = &buff_fromArray[0];

 const int inSize_const = 61;
 short inSize_short = (short) sizeof(buff_fromArray);
 int inSize_int = (int) sizeof(buff_fromArray);
 unsigned int inSize_uint = (unsigned int) sizeof(buff_fromArray);
 long inSize_long = (long) sizeof(buff_fromArray);
 long long inSize_llong = (long long) sizeof(buff_fromArray);
 size_t inSize_size_t = sizeof(buff_fromArray);

 printf ("fake iconv usage:\n");
 iconv_test((const char*) "inSize_const", (size_t*)&inSize_const);
 iconv_test((const char*) "inSize_short", (size_t*)&inSize_short);
 iconv_test((const char*) "inSize_int", (size_t*)&inSize_int);
 iconv_test((const char*) "inSize_uint", (size_t*)&inSize_uint);
 iconv_test((const char*) "inSize_long", (size_t*)&inSize_long);
 iconv_test((const char*) "inSize_llong", (size_t*)&inSize_llong);
 iconv_test((const char*) "inSize_size_t", &inSize_size_t);

 printf ("real iconv usage:\n");
 int inSize = sizeof(buff_fromArray);
 int outSize = sizeof(buff_toArray);

 iconv_t c = iconv_open("UTF-8","UTF-8");
 int status = iconv(c, &fromArray, (size_t*)&inSize, &toArray, (size_t*)&outSize);
 printf ("status=[%d], errno=[%d] \n", status, errno );

 printf ("result string:\n");
 for(size_t i = 0; i <= sizeof(buff_toArray); i++) { printf ("%c", buff_toArray[i]); }
 printf ("\n");

 int close_status =  iconv_close(c);
 printf ("close status=[%d], errno=[%d] \n", close_status, errno );

 return 0;
}
EOF

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多