NDK学习笔记(三) android studio、cmake、SWIG

SWIG是一个编译时软件开发工具,它能生成将用c/c++编写的原生模块与baokuo包括java在内的其他变成语言进行联接的必要代码。

1.下载、安装和配置

SWIG的下载:

http://www.swig.org

下载完成后,解压出来。将swig的根目录添加到系统环境变量中。
在这里插入图片描述
在这里插入图片描述
检测配置是否成功。
在这里插入图片描述

2.试用SWIG

(1).创建ndk项目
在这里插入图片描述
(2).修改CMakeLists文件

cmake_minimum_required(VERSION 3.4.1)
#寻找swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})

set(JAVA_GEN_PACKAGE "com.example.ndk2.jni")
string(REPLACE "." "/" JAVA_GEN_SUBDIR ${JAVA_GEN_PACKAGE})
set(JAVA_GEN_DIR ${Project_SOURCE_DIR}/../java/${JAVA_GEN_SUBDIR})

#文件输出目录
set(CMAKE_SWIG_OUTDIR ${JAVA_GEN_DIR})

set(CMAKE_SWIG_FLAGS -c++ -package ${JAVA_GEN_PACKAGE})
#在c ++模式下调用SWIG
set_property(SOURCE see.i PROPERTY CPLUSPLUS ON)

swig_add_library(See LANGUAGE java SOURCES See.i)

(3).创建.i文件
see.i

/*模块名see*/
%module See
//将自定义的代码包含在生成的文件中,例如编译生成的代码所需的头文件
/**
 * %<section>%{
 *
 * %}
 * <section>参数介绍:
 * begin:在生成的文件的开头位置放置代码
 * runtime:将代码块放在swig的内部类型检查及其他支持函数之后
 * header:将代码块放在header部分,这部分在头文件和其他帮助函数之后,这是生成的文件中插入
 * 代码的默认位置,可以缩写为%{...%}
 * wapper:将代码块放在生成的封装函数之后
 * init:将代码块放入装入时初始化模块的函数中。
 */
%{
#include <unistd.h>
%}

typedef unsigned int uid_t;

extern uid_t getuid(void);

(4).运行后生成文件如下
在这里插入图片描述
(5).调用后看效果

  TextView tv = findViewById(R.id.sample_text);
  tv.setText(com.example.ndk2.jni.See.getuid() + "");

在这里插入图片描述

3.SWIG的全局变量

在.i文件中声明

%module See
%{
#include <unistd.h>
  int counter;
%}

extern  int counter;

运行,SWIG生成getter和settter方法,java调用getter和settter来访问全局变量。

public class See {
  public static void setCounter(int value) {
    SeeJNI.counter_set(value);
  }

  public static int getCounter() {
    return SeeJNI.counter_get();
  }

  public static long getuid() {
    return SeeJNI.getuid();
  }

}

4.常量

.i接口文件中用#define或%constant预处理指令定义

%module See

#define  Max 9999
%constant int MAX2  = 2222;

程序讯运行后,会生成Constant的java接口文件,如下:

public interface SeeConstants {
  public final static int Max = SeeJNI.Max_get();
  public final static int MAX2 = SeeJNI.MAX2_get();
}

%javaconst
告诉SWIG生成编译时常量还是运行库常量。
作用体现在SeeConstants文件中

public interface SeeConstants {
  public final static int Max = 9999;
  public final static int MAX2 = SeeJNI.MAX2_get();
}

5.只读变量

%immutable标记只读变量
.i接口文件

/*模块名see*/
%module See

//只读变量
%immutable;
extern  int readOnlu;

%mutable;
extern  int rw;

%{
#include <unistd.h>
  int rw;
  int readOnlu;
%}

生成的文件

public class See {
	//readOnlu不生成
  public static int getReadOnlu() {
    return SeeJNI.readOnlu_get();
  }

  public static void setRw(int value) {
    SeeJNI.rw_set(value);
  }

  public static int getRw() {
    return SeeJNI.rw_get();
  }
}

6.枚举

(1)匿名枚举
.i文件中声明枚举类型

%module See
enum {one =1,two =2,three,four};

%{
#include <unistd.h>
enum {one =1,two =2,three,four};
%}

生成文件 SeeConstants

public interface SeeConstants {
  public final static int one = SeeJNI.one_get();
  public final static int two = SeeJNI.two_get();
  public final static int three = SeeJNI.three_get();
  public final static int four = SeeJNI.four_get();

}

(2)类型-安全
命名枚举展示给java的是类型-安全枚举。

/*模块名see*/
%module See
enum Num{one =1,two =2,three,four};
%{
#include <unistd.h>
enum Num{one,two,three,four};
%}

SWIG会为命名枚举定义一个单独的类。这类枚举比基于常量的方法更安全。

public final class Num {
  public final static Num one = new Num("one", SeeJNI.one_get());
  public final static Num two = new Num("two", SeeJNI.two_get());
  public final static Num three = new Num("three");
  public final static Num four = new Num("four");
  ..............

(3)类型-不安全

/*模块名see*/
%module See
//类型不安全
%include "enumtypeunsafe.swg"
enum Num{one =1,two =2,three,four};
%{
#include <unistd.h>
enum Num{one,two,three,four};
%}

生成的文件如下:

public final class Num {
  public final static int one = SeeJNI.one_get();
  public final static int two = SeeJNI.two_get();
  public final static int three = SeeJNI.three_get();
  public final static int four = SeeJNI.four_get();
}

(4)java枚举

/*模块名see*/
%module See
//类型不安全
%include "enums.swg"
enum Num{one =1,two =2,three,four};

%{
#include <unistd.h>
enum Num{one,two,three,four};
%}

生成的文件

public enum Num {
  one(SeeJNI.one_get()),
  two(SeeJNI.two_get()),
  three,
  four;
  ......
}

7.结构体

SWIG支持结构体。.i接口文件中声明结构体。

/*模块名see*/
%module See

struct  Ponit{

    int x;
    int y;
};

%{
struct  Ponit{
    int x;
    int y;
};
%}

会生成Ponit类

public class Ponit {
  private transient long swigCPtr;
  protected transient boolean swigCMemOwn;

  protected Ponit(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected static long getCPtr(Ponit obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  @SuppressWarnings("deprecation")
  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        SeeJNI.delete_Ponit(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setX(int value) {
    SeeJNI.Ponit_x_set(swigCPtr, this, value);
  }

  public int getX() {
    return SeeJNI.Ponit_x_get(swigCPtr, this);
  }

  public void setY(int value) {
    SeeJNI.Ponit_y_set(swigCPtr, this, value);
  }

  public int getY() {
    return SeeJNI.Ponit_y_get(swigCPtr, this);
  }

  public Ponit() {
    this(SeeJNI.new_Ponit(), true);
  }

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值