ndk
背景
今天没事干,就开始学习ndk开发,实现了一下Android和C的函数方法互调,记录一下步骤
步骤
1、通过Android Studio的SDK Manager安装CMake、LLDB和NDK
2、新建工程,记得要勾选inclue C++ support,而后一路next,直到完成
3、而后,在工程目录下,随便哪个子目录里,右击新建一个C源文件,同时可以勾选生成同名的头文件
4、ok后,会在指定目录下生成my_ndk_util.c/.h文件,内容如下
头文件
#ifndef MYNDKDEMO_MY_NDK_UTIL_H
#define MYNDKDEMO_MY_NDK_UTIL_H
#endif //MYNDKDEMO_MY_NDK_UTIL_H
源文件
#include "my_ndk_util.h"
5、而后,在CMakeLists.txt文本文件里,在add_library()中添加我们的源文件的相对路径,如下
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/my_ndk_util.c) # 工程目录下的相对路径
其他的都不用改
6、同步之后,在源文件里添加一个函数,完整代码如下
#include "my_ndk_util.h"
#include "jni.h"
#include "string.h"
#include "android/log.h" // 调用Android打日志方法而用
const char* tag = "my_ndk_util";
JNIEXPORT jstring JNICALL java_com_example_songzeceng_myndkdemo_MyNdkUtil_getAPPKey(JNIEnv* env, jclass type, jstring str){
char* content = "浔阳江头夜送客,枫叶荻花秋瑟瑟";
char* string = (*env)->GetStringUTFChars(env, str, JNI_FALSE); // 根据jstring获取字符串
string = strcat(string, content);
__android_log_print(ANDROID_LOG_INFO, tag, string); // 打印日志,相当于Log.i(tag, string);
return (*env)->NewStringUTF(env, content); // 根据content创建jstring
}
源文件里,头文件包含我就不说了,尤其要注意参数列表里前两个参数的位置是固定的,不能打乱,它们之后的参数都要显示写在对应的native函数的参数列表里,也是一一对应的
那么这个c函数对应的native函数在哪儿呢?看看函数名,函数名格式是Java_native函数所在类的包名_native函数所在类名_jni函数名,如包名有.分割,以_代之,所以我这个函数名就对应着com.example.songzeceng.myndkdemo包下的MyNdkUtil.java文件里的getAppKey()方法
7、在C函数对应的包名下创建MyNdkUtils类,先加载库,再定义native方法,代码如下
public class MyNdkUtil {
private static final String LIB = "native-lib";
static {
System.loadlibrary(LIB);
}
public static native String getAppKey(String s); // 这个参数s,就是C函数里的jstring参数
}
这个lib名字,是在CMakeLists.txt文件的add_library里指定的,详情请翻阅上文第5步
8、在MainActivity里,调用方法,进行验证
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedinstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = MyNdkUtil.getAppKey("白居易--");
Log.i(TAG, s);
}
}
由于在MyNdkUtil类加载的时候就加载了native库,所以不妨碍native函数的调用
效果如下:
踩的坑
1、报错cmake ERROR: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
这个由于我们是用CMake开发,不存在mk文件,所以只需要在CMakeLists.txt里加上这样一句话就可以
set(CMAKE_C_FLAGS "-Wno-error=format-security")
2、找不到asm/types.h文件,同样,在CMakeLists.txt文件里加上一句话
set(CMAKE_C_FLAGS "-isystem /Users/songzeceng/Library/Android/sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi")
路径是自己ndk目录下的sysroot/usr/include/arm-linux-androideabi
另外,我这个是用的C文件,所以是CMAKE_C_FLAGS,如果用的是cpp文件,就得是CMAKE_CXX_FLAGS
相关阅读
DirectX11 With Windows SDK--04 使用DirectX Tool Ki
前言(2018/11/4) DXTK库现在已经不随Github项目提供,因为只用到了其中的键鼠类,已经过提取加入到后续的项目中但是如果你需要配置Dire
有幸参加百度的2018年开发者大会。 李彦宏在会上推出了中国第一个无人公交车,在外面也进行展示。从造车浪潮一次次推进,到无人车开
硬件部分:先来看硬件连接图,此次实验选择ADC3的通道7,硬件原理图如图1所示,光敏电阻的原理在图1中已经说明,这里就不再多说。图2是stm3
与你一起学习MS Project——理论篇:项目管理与Project
Hi,你好!我是大黄蜂,非常高兴借此机会与你一起学习微软Project的相关知识和技能。这一次的分享主要是结合本人在实际使用Project 201
微软和许多企业都鼓励用户、开发者使用 HTML5 的通信协议,标准化通信可以极大增加网络安全性。其中包括 W3C 的 Media Source Exte