JNI开发第三篇C++实现Hello World

时间:2023-01-24 07:34:51
  • C的预处理命令
  • #开头的就是c/c++的预处理命令
  • 在编译之前 先会走预编译阶段 预编译阶段的作用就是 把 include进来的头文件 copy到源文件中
  • define这些宏定义 用真实的值替换一下
  • #if #else #endif 该删除的删除掉
  • c++开发jni代码时 env不再是结构体Jninativeinterface的二级指针
  • _JNIEnv JNIEnv _JNIEnv 是C++的结构体 C++结构体跟C区别 C++的结构体可以定义函数
  • env 是JNIEnv的一级指针 也就是结构体_JNIEnv的一级指针 env-> 来调用 结构体里的函数
  • _JNIEnv的函数 实际上调用的就是结构体JNINativeInterface的同名函数指针
  • 在调用时第一个参数 env已经传进去了
  • C++的函数要先声明再使用 可以把javah生成的头文件include进来作为函数的声明
  • include的方法 <> “” “”
  • 如果用”” 来导入头文件 系统会先到 源代码所在的文件夹去找头文件 如果找不到再到系统指定的incude文件夹下找
  • //用<> 直接到系统指定的include目录下去找

    下面通过项目具体解释一下,首先创建一个项目,就叫JNICpp。
    MainActivity

public class MainActivity extends Activity {
static{
System.loadLibrary("cpp");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void click(View v){
Toast.makeText(getApplicationContext(), helloFromCPP(), Toast.LENGTH_LONG).show();
}

public native String helloFromCPP();
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">


<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="调用C++" />


</RelativeLayout>

C++需要.h文件,所以用Javah弄一个.h文件出来
com_mengxin_jnicpp_MainActivity.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_mengxin_jnicpp_MainActivity */

#ifndef _Included_com_mengxin_jnicpp_MainActivity
#define _Included_com_mengxin_jnicpp_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_mengxin_jnicpp_MainActivity
* Method: helloFromCPP
* Signature: ()Ljava/lang/String;
*/

JNIEXPORT jstring JNICALL Java_com_mengxin_jnicpp_MainActivity_helloFromCPP
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

然后是cpp.cpp

#include <jni.h>
#include "com_mengxin_jnicpp_MainActivity.h"

JNIEXPORT jstring JNICALL Java_com_mengxin_jnicpp_MainActivity_helloFromCPP
(JNIEnv * env, jobject obj){
return env->NewStringUTF("hello from cpp");
}

最后修改一下build.gradle

apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "24.0.2"

defaultConfig {
applicationId "com.mengxin.jnicpp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
ndk {
moduleName "cpp" //生成的so名字
//abiFilters "armeabi" //输出指定三种abi体系结构下的so库。目前可有可无。
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。目前可有可无。
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.0'
}