异常捕获
// 生成so文件的名称
moduleName "joyrun"
// 引入STL标准库
stl "stlport_static"//gnustl_static
//用于解决__android_log_print
ldLibs "log"
abiFilters "armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a" //添加编译的平台
//add -fexceptions to allow throw error
//add -w to "format not a string literal and no format arguments [-Werror=format-security"
cFlags "-w -fexceptions"
LOGCAT输出
#include
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "tag_joyrun", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "tag_joyrun", __VA_ARGS__)
LOGE("Hello Logcat");
类型转换
// std::string -> jstring
std::string str = "Hello World";
jstring result = env->NewStringUTF(str.c_str());
// jstring -> std::string
jstring param;
const char *param_char = env->GetStringUTFChars(param, NULL);
std::string str = param_char;
// jboolean 两个值 JNI_TRUE、JNI_FALSE
C++调用JAVA代码
//Java
public static native void nativeToJava(NativeDemo nativeDemo);
public int subtract(int param1, int param2) {
Log.e("NativeDemo", String.format("%s - %s = %s", param1, param2, param1 - param2));
return param1 - param2;
}
//C++
JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj)
{
// 调用Java方法
jclass cls = env->FindClass("cn/taoweiji/nativemodule/NativeDemo");
jmethodID mid = env->GetMethodID(cls, "subtract", "(II)I");
int result = (int) env->CallIntMethod(obj, mid, 10, 2);
//常见类型转换例子
//String getInfo();
//-> ()Ljava/lang/String;
//PackageInfo getPackageInfo(String packageName, int flags);
//-> (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;
}
一键生成从JAVA到C++接口代码脚本
文件:autojavah.sh
#!/bin/sh
export ProjectPath=$(cd "../$(dirname "$1")"; pwd)
export TargetClassName="co.runner.app.jni.NativeDemo"
export SourceFile="${ProjectPath}/app/src/main/java"
export TargetPath="${ProjectPath}/jni-joyrun/src/main/jni"
cd "${SourceFile}"
javah -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
echo -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
五、C++面向对象及标准库入门
C++类定义
// Demo.hpp
#ifndef Demo_hpp
#define Demo_hpp
#include
#include
class Demo{
public:
std::string name;
int age = 0;
void say();
static int add(int param1,int param2)
{
return param1 + param2;
}
};
#endif /* Demo_hpp */
类方法的实现
// Demo.cpp
#include "Demo.hpp"
#include
void Demo::say()
{
std::cout<
}
对象创建及访问对象的成员
//对象创建
Demo d1;
Demo * d2 = new Demo;
// 运算符访问
d1.say();
// 指针访问
d2->say();
//静态函数访问
int result = Demo::add(1,2);
std::cout<
LIST链表
//include相关文件
#include
#include
#include
#include "Demo.hpp"
// 链表定义
std::list * demos = new std::list;
Demo * demo = new Demo;
demo->name = "Wiki";
demo->age = 24;
// 在后面插入数据
demos->push_back(*demo);
demo = new Demo;
demo->name = "Wiki2";
demo->age = 25;
// 在前面插入数据
demos->push_front(*demo);
// 顺序链表遍历
for (std::list::iterator iter = demos->begin(); iter != demos->end(); ++iter) {
iter->say();
}
// 反顺序链表遍历
for (std::list::reverse_iterator iter = demos->rbegin(); iter != demos->rend(); ++iter) {
iter->say();
}
// 获取指定位置元素
std::list::iterator iter = demos->begin();
advance(iter, 1);
iter->say();
指针、引用和值
在C++中,函数可以用许多不同的方法传递参数,比如通过指针、引用或是直接传值。
// 通过指针
void handle1(Demo *p);
// 通过引用
void handle1(Demo& p);
// 通过值
void handle1(Demo *demo);
堆和栈的理解
栈(stack):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
(责任编辑:ioter)