我正在尝试为依赖于ICU库(libicuuc.so和libicui18n.so)的C库创建一个JNI包装器。
我尝试在我的NDK中构建ICU4C(标准版和CrystaX版,在Mac OS X机器上),并继续遇到如下链接问题:
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/udata.o: In function `openCommonData':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/udata.c:836: undefined reference to `icudt42_dat'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strFromWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:365: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:415: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:314: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strToWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:164: undefined reference to `mbstowcs'
collect2: ld returned 1 exit status
我也尝试了unicode support in android ndk给出的建议,但没有运气。我陷入了困境:
arm-eabi-g++ -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -D_REENTRANT -I../common -I../../icu/source/common -I../../icu/source/i18n "-DDEFAULT_ICU_PLUGINS=\"/usr/local/lib/icu\" " -DU_COMMON_IMPLEMENTATION -DHAVE_CONFIG_H -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -std=c++0x -fvisibility=hidden -c -o errorcode.ao ../../icu/source/common/errorcode.cpp
In file included from ../../icu/source/common/unicode/ptypes.h:23,
from ../../icu/source/common/unicode/umachine.h:52,
from ../../icu/source/common/unicode/utypes.h:36,
from ../../icu/source/common/errorcode.cpp:17:
/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/sys/types.h:122: error: 'uint64_t' does not name a type
make[1]: *** [errorcode.ao] Error 1
make: *** [all-recursive] Error 2
任何帮助都将不胜感激。
答案 0 :(得分:0)
这个问题似乎涉及两个文件。调用sys / types.h的icu / source / common / unicode / ptypes.h包括
#if ! U_HAVE_UINT64_T
typedef unsigned long long uint64_t;
/* else we may not have a 64-bit type */
#endif
通过在Android中包含sys / types.h,我们涉及(接近第122/124行)
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
typedef uint64_t u_int64_t;
#endif
uint64_t在分配给u_int64_t时似乎尚未声明。实际上,sys / types.h包含stdint.h,其中包含以下内容:
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
typedef __int16_t int16_t;
typedef __uint16_t uint16_t;
typedef __int32_t int32_t;
typedef __uint32_t uint32_t;
#if defined(__STDC_INT64__)
typedef __int64_t int64_t;
typedef __uint64_t uint64_t;
#endif
未定义可能 STRICT_ANSI 。这似乎是sys / types.h中Android代码中的一个错误。如果未定义 STDC_INT64 ,则不会定义uint64_t,因此无法定义u_int64_t。也许真正的解决方案是修改sys / types.h以便它具有
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
$if defined(__STDC_INT64__)
typedef uint64_t u_int64_t;
#endif
#endif
如果你解决了这个问题,那么下一个错误将出现在cstring.h:109
中icu/source/common/cstring.h:109: error: 'int64_t' has not been declared
如果您在common / unicode / ptypes.h中改为#define STDC_INT64 ,它将会更进一步,但会以
结束icu/source/common/ustrenum.cpp:118: error: must #include <typeinfo> before using typeid
此处有更多信息:http://groups.google.com/group/android-ndk/browse_thread/thread/2ec9dc289d815ba3?pli=1但没有真正的解决方案
答案 1 :(得分:0)
我也有这个问题: 未明确引用`mbstowcs'
您应该构建并链接更高版本的android api。
注意: 我试图将它与android-ndk / platforms / android-4中的库链接...我原以为4是Android的版本,但是4是Android API的版本。和Android API 4对应的Android 1.6女巫很老了在libc中真的没有mbstowcs功能
答案 2 :(得分:0)
以下是我如何解决问题的方法。它很脏但很有效。 lib已编译:
注释掉#if U_HAVE_WCHAR_H
和相应的#endif
,以便始终包含<wchar.h>
。
将以前的uprv_wcstombs
定义替换为:
#define uprv_wcstombs(mbstr, wcstr, count) U_STANDARD_CPP_NAMESPACE wcs2mbs(mbstr, wcstr, count)
将以前的uprv_mbstowcs
定义替换为:
#define uprv_mbstowcs(wcstr, mbstr, count) U_STANDARD_CPP_NAMESPACE mbs2wcs(wcstr, mbstr, count)
在顶部的某个地方,在现有的包含下添加行:
#include "../wcsmbs.h"
size_t mbs2wcs(wchar_t * __ restrict pwcs, const char * __ restrict s, size_t n)
{
mbstate_t mbs;
const char *sp;
memset(&mbs, 0, sizeof(mbs));
sp=s;
return (mbsrtowcs(pwcs,&sp,n,&mbs));
}
size_t wcs2mbs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
{
mbstate_t mbs;
const wchar_t *pwcsp;
memset(&mbs,0,sizeof(mbs));
pwcsp = pwcs;
return (wcsrtombs(s,&pwcsp,n,&mbs));
}
希望它有所帮助。
答案 3 :(得分:0)
已经努力为作为系统一部分的ICU库提供NDK包装器:https://android-review.googlesource.com/c/153001/。