linux下使用SWIG将C/C++库移植到Java

系统:CentOS 6.6

步骤:

1、安装swig

直接 yum -y install swig即可

安装java和c++编译环境,略过

我直接 yum -y install java,发现系统已自带java

2、准备源文件和接口文件

在运行SWIG之前,首先要准备好C/C++程序的源文件(example.c),并编写接口文件(example.i)。这里采用一个简单的例子,要封装的是一个叫做example的模块。

我们要导出Example.c文件中所有变量和函数中。如下所示。

<span style="font-size:14px;">/* Example.c */
#include <stdio.h>

int integer = 100;

int add(int a, int b)
{
        return a + b;
}

char* getString()
{
        return "Some string";
}

void printLine(const char* str)
{
        printf("%s\n", str);
}</span>

新建一个文件Example.i,输入以下内容:

<span style="font-size:14px;">%module Example

%{
extern int integer;
extern int add(int a, int b);
extern char* getString();
extern void printLine(const char* str);
%}

extern int integer;
extern int add(int a, int b);
extern char* getString();
extern void printLine(const char* str);
</span>

Example.i中%module后面是库的名称,%{和%}中的内容是要加入到生成文件中的内容,通常是函数和变量的定义和要包含的头文件,作用是让生成的源文件爱女能够通过编译。之后的内容是正常的C函数和变量的定义,与正常C语言的语法相同。

3、使用SWIG生成Java类文件

现在运行命令

swig -java example.i

默认将生成 example_wrap.c, example.java, exampleJNI.java三个文件。

然后用以下命令编译共享库文件。

gcc -c -fPIC example.c example_wrap.c -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.35/include -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.35/include/linux

gcc -shared -o libExample.so example.o example_wrap.o

默认将生成 libExample.so

注意编译时要包含Java本地接口头文件jni.h所在的目录,这个文件的位置在不同系统中不同,编译时需要加入。

4、测试程序

现在就已经可以使用SWIG生成的类文件 example.java和相应的JNI文件 exampleJNI.java来调用库函数了。新建一个文件Main.java来测试一下。

public class Main{
        public static void main(String args[]){
                System.loadLibrary("Example");
                System.out.println("getInteger(): " + Example.getInteger());
                Example.setInteger(100);
                System.out.println(Example.getInteger());
                System.out.println("1 + 2 = " + Example.add(1, 2));
                System.out.println("getString(): " + Example.getString());
                Example.printLine("printString()");
        }
}

编译之前把 libExample.so 放到系统库包含目录/lib或者/usr/lib下,
即执行 cp libExample.so /usr/lib(也可以把libExample.so加到/etc/ld.so.conf,执行ldconfig)

编译运行:

javac Main.java

java Main

输出结果如下所示:

getInteger(): 100

100

1 + 2 = 3

getString(): Some string

printString()

5、总结

SWIG的功能很强大,可以支持很多语言。这里只测试了Java语言的封装,对于其他语言,方法也比较类似,只是在编译的时候需要包含相应的本地库头文件,如Python中的Python.h,Java中的jni.h。另外,这里演示的只是最简单的接口文件的编写,实际上,接口文件可以有更多的选项,这些在SWIG的文档中有更详细的说明。C语言的封装相对比较简单,对于C++这样的面向对象的语言,接口文件的编写略微复杂,但是也比较容易掌握。当然,在调用这些本地接口的时候还有一个问题,就是安全性。在设计接口的时候也要充分意识到安全性问题,防止指针错误和内存泄漏等。虽然SWIG已经能够很好地处理指针,但有的时候还需要自己去实现指针的封装。

时间: 2024-11-10 01:38:49

linux下使用SWIG将C/C++库移植到Java的相关文章

linux下编译qt5.6.0静态库——configure配置

 随笔 - 116  文章 - 4  评论 - 7 linux下编译qt5.6.0静态库--configure配置 linux下编译qt5.6.0静态库 linux下编译qt5.6.0静态库 configure生成makefile 安装选项 Configure选项 第三方库: 附加选项: QNX/Blackberry选项: Android 选项: 生成makefile 遇到链接检查失败的情况 生成makefile后进行编译 编译时的错误 多重定义'QT_MODBUS()'和'QT_MODBU

[转]Linux下用gcc/g++生成静态库和动态库(Z)

Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10|  分类: linux |  标签:链接库  linux  g++  gcc  |举报|字号 订阅 在 linux 下,库文件一般放在 /usr/lib 和 /lib 下, 静态库的名字一般为 libxxxx.a ,其中 xxxx 是该 lib 的名称 动态库的名字一般为 libxxxx.so.major.minor , xxxx 是该 lib 的名称, major 是主版本号, minor 是副版本号

Linux下安装PHP的GD支持库

Linux下安装PHP的GD支持库 1.安装 zlib  wget ftp://ftp.sunfreeware.com/pub/freeware/SOURCES/zlib-1.2.3.tar.gz tar -zxf zlib-1.2.3.tar.gz cd zlib-1.2.3 ./configure –prefix=/usr/local/zlib make make install 2.安装 jpeg wget ftp://ftp.sunfreeware.com/pub/freeware/SO

Linux下Gcc生成和使用静态库和动态库详解

参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主要是编译器.汇编器和连接器的不同),因此二者库的二进制是不兼容的. 本文仅限于介绍linux下的库. 1.2库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同

【转】Linux下gcc生成和使用静态库和动态库详解

一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主要是编译器.汇编器和连接器的不同),因此二者的库的二进制是不兼容的. 本文仅限于介绍linux下的库. 1.2 库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大. 共享库的代码是在可

linux下的动态链接库和静态链接库到底是个什么鬼?(二)动态链接库的编译与使用

上一篇文章里讲解了linux下静态链接库的编译与使用,下面我们来聊聊动态链接库的编译与使用方法. 所谓动态链接库,也就是说编译的时候不会真的把你引用到的库给编到你的执行程序里,而是在执行时候才会去加载相关的库,所有用到此库的程序可以共享一份代码,这样带来的好处是可执行程序所占的空间变小了,同时,如果库需要升级,你并不需要重新编译你的程序,只要把相关的库升级即可. 接下来我们来看看动态链接库的编译与使用方法,代码还是和上文中的一样,分别为?sum.c, sum.h, 和main.c, 在linux

linux下动态链接库.so文件 静态链接库.a文件创建及使用

转摘网址为:http://www.cnblogs.com/fengyv/archive/2012/08/10/2631313.html Linux下文件的类型是不依赖于其后缀名的,但一般来讲:    .o,是目标文件,相当于windows中的.obj文件    .so 为共享库,是shared object,用于动态连接的,和dll差不多    .a为静态库,是好多个.o合在一起,用于静态连接    .la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息.可以用如下命令

linux下添加动态链接库路径、动态库加载等方法

linux下添加动态链接库路径的方法 2017年01月20日 10:08:17 阅读数:5596 Linux共享库路径配置 Linux下找不到共享库文件的典型现象为明明已经安装某个软包(如libnet,MySQL),编译连接可以正常进行,但是在运行时出现如"error while loading shared libraries: libnet.so.1:cannot open shared object file :No such file or directory"的错误提示. 原

Linux下编译Android平台的ffmpeg库

在Linux平台下编译要方便些,我这里使用的环境是openSUSE,用Ubutunu也是一样的. 首先你需要Android-NDK 和ffmpeg源码,不同的版本里的文件结构有所差别,编译环境也有所不同.我这里使用的是以下两个版本: android-ndk-r8-linux-x86.tar.bz2 ffmpeg-0.7.17.tar.gz 1. 解压 android-ndk-r8-linux-x86.tar.bz2 cd ~ tar xvf android-ndk-r8-linux-x86.ta