Android之NDK开发问题解决办法

来源:互联网 发布:淘宝网汉服女装 编辑:程序博客网 时间:2024/05/17 01:00

Android之NDK开发问题解决办法


问题一:Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml    (这个是NDK工具的一个BUG,若build Target大于minSdkVersion,则会报这个错误,导致无法运行)
解决方法:
android-ndk-r8e/build/core/add-application.mk第128行把__ndk_warning改为__ndk_info;然后重新build一次项目即可消除错误。


问题二:使用c++来编写本地库,会有一些兼容问题。
(1)直接黏贴HelloJni的stringFromJNI函数过来测试,提示Method 'NewStringUTF' could not be resolved
解决方法:
改为:将(*env)->NewStringUTF(env, "Hello from JNI !")改为return env->NewStringUTF("Hello from JNI !")即可
原因是:
NDK plugin默认为我们生成的是cpp文件,而C与C++调用函数的参数不一致,因此找不到函数,具体参考jni.h中的定义。cpp文件中形如(*env)->Method(env, XXX)改成env->Method(XXX)即可。


(2)运行c++生成的.so库,若报以下错误:(既找不到函数)
No implementation found for native Lcom/dgut/android/MainActivity;.stringFromJNI ()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: stringFromJNI
at com.dgut.android.MainActivity.stringFromJNI(Native Method)
解决方法:
为供Java调用的c++函数前加入extern "C" 修饰,如:(NDK example里面的cpp文件也是这么声明的,参考hello-gl2)

extern "C" {
JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz );
}

JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )
{
    return env->NewStringUTF("Hello from JNI bear c++");
}
原因是:       被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。
       首先看看C++中对类似C的函数是怎样编译的:作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数voidfoo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。
同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

因此,若我们没有使用extern "C"修饰函数,按照C语言方式编译和连接,Jni调用将可能找不到该函数。


问题三:NDK开发中Eclipse报错“Unresolved inclusion jni.h”

在做NDK开发过程中有时候在eclipse里会遇到其无法处理inclusion导致symbol显示错误,网上有许多方法可以解决类似“Unresolved inclusion jni.h” 错误的方法,包括include path等方法,不过对我都不管用。
最终的解决办法就是初始化eclipse对该project的native support:
1. 在eclipse中关闭指定Project
2. 用其他编辑工具打开该project的.project文件,删除以下内容:
......
 <buildCommand>
 <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
 <triggers>clean,full,incremental,</triggers>
 <arguments>
 </arguments>
 </buildCommand>
 ......
 <buildCommand>
 <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
 <triggers>full,incremental,</triggers>
 <arguments>
 </arguments>
 </buildCommand>
......
<nature>org.eclipse.cdt.core.cnature</nature>
 <nature>org.eclipse.cdt.core.ccnature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
3. 删除.cproject文件
4. 在eclipse里打开原来的project, refresh,然后右键->properties->Android Tools -> Add Native Support
5. 搞定



0 0
原创粉丝点击