JNI学习第八天(一) Java和native相互调用

前几天我们学习了c的基础知识和jni的一些基本数据类型的对应关系。接下来几天开始进如JNI的练习。

学习之前我们要先来弄懂要学什么?

接下来分析下:

一、java调用c

二、c调用java

三、自己编写c的内容。

我们前期先主要围绕前两种来学习。

学习之前我们首先要做的就是学习怎么打印Log日志,当然这个Log是在Jni中打印的。我们知道c的打印一般就是printf()

但是这个方法在Android studio中没法显示结果的。

----------------------------------------------------话不多说撸代码-------------------------------------------------

1.1:如果你的开发工具是Android studio 并且你的NDK配置文件是CMakeLists.txt可以用下面的方法

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

在这里面引入你的log

1.2:接着在你需要打印的.cpp文件下引入

#include <android/log.h>

 

#include <jni.h>这个开发中会用到

 

#define TAG "我的LOG日志"//这个TAG的内容自己随便定义,跟我们Android的tag一样
// 本人喜欢用LOGE的所以这边用了ANDROID_LOG_ERROR  error级别的打印。
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)

其他的两个定义方式:

// 定义info信息
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
// 定义debug信息
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

ANDROID_LOG_INFO:是日志级别;
TAG:是要过滤的标签,可以在LogCat视图中过滤。
__VA_ARGS__:是实际的日志内容。

LOGE(...)  ...代表个数可变参数。

比如接下来我们要打印一个数值:

jint i=1;
LOGE("我的int值是%d",i);

1.3日志类型
1)Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v(,);
2)Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择
3)Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
4)Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
5)Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。

LOGI("user info----name:%s, age:%d, sex:%s.", "xxx", 18, "男");

对应的占位符可以查看我之前写的,或者到网上搜一下吧。

注意:log打印的方法中不能传入jstring,必须将jstring转为c中的字符数组在传入到方法里面打印,否则会报错。

2.1:如果你的开发工具是Android studio 并且你的NDK配置文件是Android.mk可以用下面的方法

如生成的库文件是“.so文件”,则在Android.mk中添加如下内容:
LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog
如生成的库文件是“.a文件”,则在Android.mk中添加如下内容:
LOCAL_LDLIBS:=-llog

defaultConfig {
        applicationId "im.weiyuan.com.jni"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk{
            moduleName "hello"  //设置库(so)文件名称
            abiFilters "armeabi", "armeabi-v7a", "x86"
            ldLibs "log"
        }

    }

其他的操作跟1.1的雷同了。

这时篇幅太长了,另开一章咯~~~。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JNIJava Native Interface)是 Java 虚拟机提供的一组本地函数接口,用于实现 Java 与本地代码的交互。在开发过程中,我们需要将 Java 代码和本地代码进行交互,就需要用到 JNI。 下面是一个简单的 JNI 接口示例: ```c // test.c #include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_Test_print(JNIEnv *env, jobject obj, jstring str) { const char *c_str = (*env)->GetStringUTFChars(env, str, NULL); printf("%s\n", c_str); (*env)->ReleaseStringUTFChars(env, str, c_str); } ``` 在上述代码中,我们定义了一个 JNI 接口函数 `Java_Test_print`,用于从 Java 代码中调用。函数的意义是打印一个字符串。 接下来,我们需要将本地代码编译为共享库,并将其与 Java 代码进行链接。在 Linux 系统中,可以使用以下命令编译共享库: ```bash gcc -shared -fpic -o libtest.so test.c -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" ``` 其中,`$JAVA_HOME` 表示 Java 安装路径。编译完成后,我们将共享库文件 `libtest.so` 放置到 Java 代码所在的目录中。 最后,我们在 Java 代码中调用 JNI 接口函数: ```java // Test.java public class Test { static { System.loadLibrary("test"); } private native void print(String str); public static void main(String[] args) { Test test = new Test(); test.print("Hello, world!"); } } ``` 在上述代码中,我们使用了 `System.loadLibrary()` 函数加载共享库文件 `libtest.so`,并定义了一个 `print()` 方法,用于调用 JNI 接口函数 `Java_Test_print`。 当我们运行 Java 代码时,就会输出字符串 `"Hello, world!"`。 需要注意的是,JNI 接口函数的命名规则为 `Java_类名_方法名`,其中类名需要使用下划线代替点号。在函数的参数列表中,第一个参数为 `JNIEnv` 指针,第二个参数为 `jobject` 类型的对象指针,用于表示调用该函数的 Java 对象。接下来的参数为 Java 方法的参数列表。 在 JNI 接口函数中,我们需要使用 `(*env)` 操作符访问 `JNIEnv` 指针所指向的函数表。例如,在上述代码中,我们使用 `(*env)->GetStringUTFChars()` 函数获取字符串的 UTF-8 编码,并在使用完毕后使用 `(*env)->ReleaseStringUTFChars()` 函数释放该字符串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rnwater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值