JNI/NDK 开发 C/C++ 典型基础知识点

1.引入动态裤

// path 路径:加载一个具体路径下的so库,可以是从服务器下载下来的(必须要下载到data/data/目录下面)。
System.load(path);
//path 加载本地 lib下面的so库。
System.loadLibrary(path);

2.c语言中方法不能重载,c++中方法能重载。

3.JNIEnv对象

JNIEnv:在c中是结构体指针(方法中是二级指针),在c++中是结构体(方法中是一级指针)。
且JNIEnv在整个内存中只有一个对象。

4.获得java类中的方法/属性的签名

获得java类中的方法/属性的签名
javap -s xxx.class
android studio需要 cd 到
build/intermediates/classes/… 
or
build/intermediates/javac/debug/compileDebugJavaWithJavac/classes...

5.const关键字 定义值不变的恒定的

const int a;
int const a;
这两个是一样的 都是a这个值不可改变。
const int *a;
int * const a;
这两个就有不同了。
第一个*a不能变,具体值不能变,第二个a不能变,指针不能变(地址不能变)

6.strcmp(const char *s1,const char * s2)比较大小

原型:extern int strcmp(const char *s1,const char * s2);
用法:#include <string.h>
功能:比较字符串s1和s2。
说明:
当s1<s2时,返回值<0
当s1=s2时,返回值=0
当s1>s2时,返回值>0

7.引包

#include <string> 系统的包
#include "xxx.h" 我们自己导入的c/c++文件

8.Void*

Void可以代表任意的数据类型
Void i;//错误的,因为无法分配内存大小
Void* i //没问题,任意类型的指针

9.内存四区模型

栈区:由编译器自动分配的,存放一些局部变量和函数,这个里面内存是会自动进行回收的
堆区;一股都是由我们自己去开辟的,这个里面的内存需要手动进行释放malloc-free, new-delete
全局区:静态的一些常量,字符串等等
程序代码区:存放的是函数体的二进制代码

10.宏定义函数

1.宏定义不是语句,是预处理指令,故结尾不加分号。
#define N 5; //虽语法正确,但会把N替换成5;
函数式宏定义:#define MAX(a,b) ((a)>(b)?(a):(b))
普通函数    : MAX(a,b) { return a>b?a:b;}
例子:
#define Jin(NAME) java_jin_##NAME

std::string java_jin_wirte(char* c){
    return c;
}

std::string java_jin_read(char* c,int a){
    return c;
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_ts_javatoc_MainActivity_getJin(JNIEnv *env, jobject instance) {
    std::string hello = Jin(read)("这是宏定义函数",2);
    return env->NewStringUTF(hello.c_str());
}

11.struct结构体和class类有什么区别

1.在C中STRUCT是用来封装数据的,其中不能够有函数成员。而在C++中继承了在C语言中的用法,
但是又做了改进,那就是在STRUCT 中允许有成员函数,这时候的STRUCT和类就没有什么本质的
区别了。STRUCT也能使用继承,多态,重载。
2. 唯一的区别: 就是STRUCT中的变量默认存取权限是PUBLIC的,CLASS中的是PRIVATE,
所以既可以使用STRUCT也可以用CLASS,至于权限问题,自己用PUBLIC,PRIVATE,PROTECTED
关键字指定就可以了。在类的定义中,声明成员变量不能同时对其初始化。
例如:
CLASS A { INT A=0;//错误,声明成员变量不能初始化 };
3.在表示接口或者简单的数据集合时一般用struct关键字,表示c++的抽象数据类型时,一般用class。

12. c++的模板类使用

如果开发中设计到模板类template<class/typename T> ,声明和实现要写到同一个类中hpp 文件= h + cpp;

#ifndef JAVATOC_TESTT_HPP
#define JAVATOC_TESTT_HPP

template <class T>
class MyTemplateName{
private:
    T index;
    char *x;
public:
    MyTemplateName();
    T getIndex();
    void setIndex(T dex);
    // 析构函数
    ~MyTemplateName();
};

#endif //JAVATOC_TESTT_HPP

template <class T>
//此处必须加上<T> -- MyTemplateName<T>
MyTemplateName<T>::MyTemplateName() {
}

template <class T>
void MyTemplateName<T>::setIndex(T dex) {
    this->index = dex;
}

template <class T>
T MyTemplateName<T>::getIndex() {
    return this->index;
}

13. c++中的vector/set集合注意的问题

c++中集合有vetcor 和 set 但是在使用的时候不仅要导入包还必须要加
using namespace std;声明域不然找不到,其实vector是在命名空间中:

#include <set>
#include <vector>

using namespace std;

vector<string> sv;
sv.push_back("s");
sv.pop_back();

set<string> set1;
但是一般我们尽量少用命名空间关键字,防止我们在引用的时候出现重复的类或者方法
所以采用
std::vector<std::string> sv;
sv.push_back("s");
sv.pop_back();

std::set<std::string> set1;

14. 预定义函数对象和函数适配器

常用预定义函数对象:算法,循环,增,删,改,查(c++定义好的方法)
循环:foreach,transform(有返回值循环),
查找:find,find_if,
统计:count,count_if,
合并:megre,
排序:sort,
打乱:random_shuffle ,copy,replace

函数适配器:bind2nd()等
例子:https://www.cnblogs.com/smh2015/p/9656648.html

15. c/c++参数传递

需要注意的是在c/c++中 传递参数(对象)时要传递 对象的指针/引用,因为方法在接受到参数时候,得到的对象是一个自己创建的新的object对象:

正确:
Bitmap2mat(JNIEnv *env, Mat *mat)
Bitmap2mat(JNIEnv *env, Mat &mat)
错误:
Bitmap2mat(JNIEnv *env, Mat mat)

总结:c/c++ 的STL细想就是集合,迭代器,算法的分离。

发布了119 篇原创文章 · 获赞 140 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/WangRain1/article/details/94562527
今日推荐