视频课程:Java与JNI基础数据类型转换,Android CMake以及NDK实践基础教程-慕课网
上代码:base.h
#include <android/log.h>
#include <jni.h>
#ifndef MY_APPLICATION_BASE_H
#define MY_APPLICATION_BASE_H
#define LOG_TAG "NativeMethod"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#endif //ANDROIDCPPSOLIB_LOGUTIL_H
jni_basic_type.cpp
#include <jni.h>
#include <string>
#include "base.h"
extern "C"
JNIEXPORT jint JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeInt(JNIEnv *env, jobject thiz,
jint num) {
LOGD("JAVA int value is %d", num);
int c_num = num * 2;
return c_num;
}
extern "C"
JNIEXPORT jbyte JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeByte(JNIEnv *env, jobject thiz,
jbyte b) {
LOGD("java byte value is %d", b);
jbyte
c_byte = b + (jbyte)
10;
return c_byte;
}
extern "C"
JNIEXPORT jchar JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeChar(JNIEnv *env, jobject thiz,
jchar ch) {
LOGD("java char value is %c", ch);
jchar
c_char = ch + (jchar)
3;
return c_char;
}
extern "C"
JNIEXPORT jshort JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeShort(JNIEnv *env, jobject thiz,
jshort sh) {
LOGD("java char value is %d", sh);
jshort
c_short = sh + (jshort)
10;
return c_short;
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeLong(JNIEnv *env, jobject thiz,
jlong l) {
LOGD("java long value is %ld", l);
jlong c_long = l + 100;
return c_long;
}
extern "C"
JNIEXPORT jfloat JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeFloat(JNIEnv *env, jobject thiz,
jfloat f) {
LOGD("java float value is %f", f);
jfloat
c_float = f + (jfloat)
10.0;
return c_float;
}
extern "C"
JNIEXPORT jdouble JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeDouble(JNIEnv *env, jobject thiz,
jdouble d) {
LOGD("java double value is %f", d);
jdouble c_double = d + 20.0;
return c_double;
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_jszy_jni_JNIBasicType_callNativeBoolean(JNIEnv *env, jobject thiz,
jboolean value) {
LOGD("java boolean value is %d", value);
jboolean
c_bool = (jboolean)
!value;
return c_bool;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project("cmakedemo")
#静态
add_library(
cmakedemo
SHARED
native-lib.cpp)
#与‘cmakedemo’链接在一起
add_library(
people-lib
SHARED
people/people.cpp)
#动态注册
add_library(
native-lib
SHARED
jni/jni_dynamic_load.cpp
jni/jni_basic_type.cpp
)
add_library(base-lib
SHARED
base/base.cpp
base/jvm.cpp
)
#添加搜索路径
include_directories(${CMAKE_CURRENT_LIST_DIR}/people/)
include_directories(${CMAKE_CURRENT_LIST_DIR}/base/)
#查找动态库
find_library(
log-lib
log)
#动态库关联
target_link_libraries(
cmakedemo
people-lib
${log-lib})
target_link_libraries(
native-lib
base-lib
${log-lib})
关键问题解决: 我把动态关联库分开写就解决了这个问题
由原来的:
#动态库关联
target_link_libraries(
cmakedemo
people-lib
native-lib
base-lib
${log-lib})
修改为:
#动态库关联
target_link_libraries(
cmakedemo
people-lib
${log-lib})
target_link_libraries(
native-lib
base-lib
${log-lib})
就可以,虽然解决了,但是不明白为什么这样... 难道关联太多了....
我明明在jni_basic_type.cpp中引入了#include "base.h" 使用LOGD 也没有报错...但是就是编译不过。反正问题解决了。
运行结果:确实按到程序逻辑运行了
2021-10-15 14:03:33.818 9808-9808/com.jszy.cmakedemo D/NativeMethod: JAVA int value is 100
2021-10-15 14:03:33.858 9808-9808/com.jszy.cmakedemo I/MainActivity:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ main, com.jszy.cmakedemo.MainActivity.lambda$onCreate$1(MainActivity.java:38)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ java show 200
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
参考:Android ndk(cmake): 'undefined reference to `__android_log_write' when using log api in the second jni library - Stack Overflow
吐槽一下,其他博文大多数是基于Android.mk的 没得参考意义,10个博文9个一样...还没实际解决问题..恼火!!!!!!!!!!