Android自助餐之Jni进阶
Posted -_-void
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自助餐之Jni进阶相关的知识,希望对你有一定的参考价值。
android自助餐之Jni(五)进阶
C2C++(待完善)
函数声明
- Java类:
package.name.ClassName.methodName()
;Java方法:public native String methodName(String value)
- C:
JNIEXPORT jstring JNICALL Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value)
- C++
//声明
extern "C"{
jstring Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value);
}
//定义:
jstring Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value){...}
方法调用
- GetStringUTFChars
- C:
char * str = (*env)->GetStringUTFChars(env,value,NULL);
- C++:
const char * str = env->GetStringUTFChars(value,NULL);
- C:
- NewStringUTF
- C:
(*env)->NewStringUTF(env, str);
- C++:
env->NewStringUTF(str);
- C:
- sprintf
- C:使用前只需定义第一个参数
char * str;
- C++:使用前需定义第一个参数并为其分配空间
char * str = (char*)malloc(sizeof("size you need"))
- C:使用前只需定义第一个参数
使用androidLog
- 配置
build.gradle
android {
//...
defaultConfig {
//...
ndk{
//...
ldLibs "log", "z", "m"
}
}
}
- include
在用到log的C/C++中#include <android/log.h>
- 调用log
__android_log_write(ANDROID_LOG_ERROR, "tag","message");
模块化
当jni文件夹下文件过多不好管理时,可以再jni下新建子文件夹来将文件分模块管理,引用时写上子文件名即可。例文件jni/file.h
移到jni/file/file.h
,对应的include "file.h"
改为include "file/file.h"
。
类型转换
- java中的String
在C/C++中用jstring接收,用char*操作,jstring与char*的转换见上述(C2C++) - java中的int
在C++中用int接收。
操作bitmap
- java代码
public native void fun(Bitmap bmp);
- C++头文件
#include <android/bitmap.h>
- C++代码
void Java_package_name_ClassName_fun(JNIEnv *env,jobject obj,jobject bmp){
AndroidBitmapInfo bmpInfo={0};
if(AndroidBitmap_getInfo(env,bmp,&bmpInfo)<0){return;}
unsigned char * dataFromBmp=NULL;//此指针即指向bitmap数据的指针
if(AndroidBitmap_lockPixels(env,bmp,(void **)&dataFromBmp)){return;}//获取并锁定bitmap在内存的地址
//do something with dataFromBmp
AndroidBitmap_unlockPixels(env,bmp);//操作结束后需要解锁改地址
}
- 配置build.gradle
android {
//...
defaultConfig {
//...
ndk{
//...
ldLibs "jnigraphics"
}
}
}
- 配置Android.mk
LOCAL_LDLIBS := -ljnigraphics
- clean project
其他
- 使用标准库STL
- 在jni下新建文件
Application.mk
并写入APP_STL := stlport_static
- 在build.gradle中配置
android {
//...
defaultConfig {
//...
ndk{
//...
stl "stlport_static"
}
}
}
- 在jni下新建文件
开启异常控制(可以在cpp中throw)
android { //... defaultConfig { //... ndk{ //... cFlags = "-fexceptions" } } }
error: undefined reference to xxx
一般该错误会在cpp中报出,找到对应的h文件,做如下修改#ifndef _A_H #define _A_H #ifdef __cplusplus extern "C"{ #endif ...(文件原有代码) #ifdef __cplusplus } #endif #endif // endof _A_H
const char *
转unsignde char *
//const cahr * str=...; unsigned char * data=(unsigned char *)(const_cast<char*>(str));
以上是关于Android自助餐之Jni进阶的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印内容带有文件文件名方法名行号 等信息,方便定位日志输出的地方
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印内容带有文件文件名方法名行号 等信息,方便定位日志输出的地方