在Android JNI环境下使用C++的几个问题与解决

序言

在测试tinythread++库在不同移动平台下的可用性时,碰到几个问题。tinythread++号称是兼容c++11标准的thread库,当不能使用c++11时可以使用之。未来c++11更为流行时可轻易更换。


不同平台下的测试状况:
  • iOS: 通过。需要将调用c++代码的.m文件更名为.mm文件。
  •  WP: 未知。暂未涉及。
  • Android: 通过。在解决了下面的几个问题之后。

Android JNI环境下的C++问题:

1) error: base operand of '->' has non-pointer type '_JNIEnv'

C++的调用方式与C有所不同,比较:
C++:  env->NewStringUTF("JNI C++!");
  C:  (*env)->NewStringUTF(env, "JNI C!");
举例:
jstring
Java_com_listthrd_MainActivity_runListThrd( JNIEnv* env,
                                                  jobject thiz )
{
  // for C++
  return env->NewStringUTF("JNI C++!");
  // for C
//  return (*env)->NewStringUTF(env, "JNI C!");
}

2) error: iostream: No such file or directory

找不到iostream等stl库文件,这是由于ndk默认不使用stl。解决:
在jni目录创建Application.mk文件,加入一下内容:
#APP_STL:=stlport_static
APP_STL := gnustl_static
以上,二选一即可。推荐gnustl,因为可以解决其它问题,见后。

3) error: 'terminate' is not a member of 'std'

当使用stlport时会产生这个错误。改用gnustl_static即可。

4) undefined reference to `__cxa_end_cleanup'

当使用stlport时会产生这个错误。因此改用gnustl_static。

5) undefined reference to `__android_log_print'

这是未链接上Android的log库。在Android.mk文件中添加LOCAL_LDLIBS定义,如下:
#LOCAL_EXPORT_LDLIBS := -llog
LOCAL_LDLIBS := -llog
以上,LOCAL_EXPORT_LDLIBS在C语言时好用,此处可去掉。

6) ERROR/AndroidRuntime(330): FATAL EXCEPTION: main
        java.lang.UnsatisfiedLinkError ...

需使用C语言风格的调用约定,在导出的JNI函数前添加extern
"C"指定,或用花括弧括起JNI导出函数。例如:
extern "C" {
  JNIEXPORT jstring JNICALL
  Java_com_listthrd_MainActivity_runListThrd( JNIEnv* env, jobject thiz )
  {
    // ...
  }
}

【附】

1、TinyThread++: http://tinythreadpp.bitsnbites.eu/

你可能感兴趣的:(C++,android,exception,jni,iostream,reference)