使用SWIG,在java编程中调用动态库

SWIG是一个开源工具,用于将C和C++程序与脚本语言(如Python、Java)等高级编程语言连接。它自动生成必要的‘胶水代码’,简化了跨语言调用的过程,避免手动编写JNI等接口代码的繁琐工作。通过SWIG,开发者可以更高效地集成C/C++库到其他语言项目中,减少错误和提高开发效率。
摘要由CSDN通过智能技术生成

1. SWIG是什么?

    SWIG的官方网站是 http://www.swig.org/ 。

    官方网站第一句话:SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. ... ... SWIG is typically used to parse C/C++ interfaces and generate the 'glue code' required for the above target languages to call into the C/C++ code. ... ... SWIG is free software and the code that SWIG generates is compatible with both commercial and non-commercial projects.

    翻译一下: SWIG是一种软件开发工具,可将用C和C ++编写的程序与各种高级编程语言相连接。... ... SWIG通常用于解析C / C ++接口并生成上述目标语言调用C / C ++代码所需的“胶水代码”。 ... ... SWIG是免费软件,SWIG生成的代码与商业和非商业项目兼容。

   其中, “上述目标语言”,包括:脚本语言,如Javascript、Perl、PHP、Python、TCL和Ruby。非脚本语言,如C#、D、GO语言、Java、Lua、OCaml、Octave、Scilab和R。

    也就是说,SWIG是 可以为其他语言比如Python、java等,生成能够调用使用C和C++编写的库的相关代码的 一个免费软件。

2. SWIG能做什么?

    我个人认为,SWIG就是要为其他编程语言生成 能够调用 C和C++编写的库 的中间代码。 

    举个例子,如果你知道Java 可以通过JNI 调用C和C++,那么SWIG也就是 “做JNI的事情”。

    这里先解释一下 “做JNI的事情”:

    当我们在进行Java开发时候,在某些情况下是要调用C开发的库。但Java代码是没办法直接调用C开发的库,需要做大致两个步骤的开发才可行:

    第一步,你要写一个Java层的代码,加载so库,以及声明一个native方法:

//MyFunJNI.java文件,包名为: com.my.fun
public class MyFunJNI {
  static {
      System.loadLibrary("myfun");
  }
  public final static native int doFun();
}

    第二步,你要编写一个C层代码,对应第一步MyFunJNI中的doFun方法,并调用到你想要使用的C开发的库中的函数 int c_fun():    

/myjni.c
jint Java_com_my_fun_MyFunJNI_doFun(JNIEnv *env,jobject thiz){
    return c_fun();
}

    然后将myjni.c编程库,比如libmyfun.so,将这个libmyfun.so和C编写的库,放在java程序运行时能加载到的位置。

    这样java程序就能调用C开发的库中的方法了。

    

    在大部分情况下,第二步的代码编写是一个从Java翻译成C的枯燥无味的工作,尤其是里面涉及一些类型的转换工作,写的不熟悉的话还得自己动手查或者从别处copy。

    但如果是使用了SWIG,那就不需要我们自己动手写第一步和第二步中的相关代码了,因为SWIG可以帮我们生成。

    因此,我觉得SWIG做的事情,就是将你从“沉重枯燥易出错”的工作中解脱出来。

 

3. SWIG怎么用?

    要想使用SWIG,需要先下载SWIG,可以在 https://sourceforge.net/projects/swig/files/ 下载自己操作系统对应的包。(如果感兴趣的话,官方也提供了源码以及在不同操作系统上的编译方法,自己可以动手修改编译。)

    我使用的是Windows,因此我下载的是最新版本的 https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.0.2/

    下载完成之后并解压,然后配置SWIG的环境变量。配置完成之后,打开cmd窗口,输入swig 试试,是否配置好了。

    先简单的看一下,swig怎么使用,这里以Android开发为例,以下是在Android Studio中进行的,这里默认NDK等相关开发环境已经准备好了,也已经建好了一个正常的APP Module,目录结构如下所示:

    libs下的libmyfun.so(这里libmyfun.so跟上面第2节中的libmyfun.so不是同一个,这里的是个纯粹功能的库)为已经用C写好的so库,并且知道要使用so库中的函数为:int doFun();

 

   (a). 先编写一个以 ".i"结尾的文件myswig.i,放到跟这个Module的build.gradle同一级目录(其实myswig.i可以放在任何位置),这个文件用于生成JNI对应的Java代码和C代码,myswig.i的内容为:

%module MySwig
%inline %{
extern int doFun();
%}

(b). 然后使用命令:

swig -java -package com.my.fun -outdir ../java/com/my/fun  -o ./myfun_wrap.c myswig.i
//注意,这个命令中,是在配置好swig的环境变量之后,在myswig.i这个文件所在的目录下执行的
//可以通过swig -help 命令查看参数含义
//其中 -java 表示要产生java相关文件
//-package 生成java文件的包名
//-outdir 表示将产生的java文件输出到的目录
//-o 表示产生的C或C++文件路径

  执行这个命令后,会生成几个文件:

   myswig_wrap.c,MySwig.java,MySwigJNI.java

打开myswig_wrap.c文件之后发现里面发现有很多代码,其中最主要的代码为:

打开MySwigJNI.java 和 MySwig.java分别是:

   

这么看来,如果我们自己写JNI相关的代码,也基本是这样的代码。

(c). 最后在编写CMakeLists.txt文件,把生成myswig_wrap.c编译成libmyswig.so库,以及在MainActivity中使用MySwigJNI的doFun方法,运行一遍看看效果。

    不过,不要忘了在java文件中加上 加载 System.loadLibrary("myswig"); 加载编译好的libmyswig.so库。

 

4. 最后

    这里介绍的是SWIG最最基本的用法。

    SWIG有一些团队学习成本,但它也能减少一些机械重复的编码工作。具体要不要在实际项目中使用SWIG,是仁者见仁智者见智的。

    具体更多的用法可以参看官网:http://www.swig.org/

    如果是做java或Android开发的,也可以看看:

    http://www.swig.org/Doc1.3/Java.html

    http://www.swig.org/Doc2.0/Android.html#Android_examples_intro

    另外,https://www.jianshu.com/p/8d8fdb095f88 (Swig java Jni开发指南)写的也挺详细的。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值