سؤال

I have a bit of code that uses iconv() on Linux to validate a string as being UTF-8 encoded. The conversion I create like:

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

I run iconv() like:

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

I then take the string to have valid UTF-8 if status is not -1.

This compiles and works fine in a 32 bit environment (where it was initially developed and tested). However I now have a requirement to get this working in a 64 bit environment (to be specific the 64 bit flavor of Fedora 14 I believe). When I compile and run a test on this there status is always -1 and I always get an EILSEQ error in errno, even for the same string which the 32 bit compile says is fine.

Does anyone have any ideas as to why this might be happening?

هل كانت مفيدة؟

المحلول

Recently had experienced same issue. Casting to (size_t*) is more (very) likely the root cause. The problem even could be easy simulated with next code:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top