SWIG(Simplified Wrapper and Interface Generator)是一个将C/C++接口转换为其他语言接口的工具,从而可以讲C/C++的库集成到其他语言的系统中。目前SWIG已经可以支持Python, Java, C#,Ruby,PHP,R语言等十多种语言。

本文介绍一下在Liuux平台上如何将C++接口转换为Java接口。

一、首先先编写一个C++的动态库。

代码如下:

1、接口文件定一个。

C++没有像Java/C#一样的interface关键词,但是可以用虚基类来定义接口个,虚基类同样是只有定义,没有实现类,它的功能现放在继承类中实现。

C++ geometryapi.h代码

#ifndef __GEOMETRY_API_H__

#define __GEOMETRY_API_H__

//===========================================================================

class Geometry;

class GeometryFactory;

//---------------------------------------------------------------------------

/*

* 说明:几何对象类

*/

class Geometry

{

public:

Geometry(){}

virtual ~Geometry(){}

public:

virtual const char* GetType() =0;

virtual void Release() =0;

};

//---------------------------------------------------------------------------

/*

* 说明:几何对象工厂类

*/

class GeometryFactory

{

public:

GeometryFactory(){}

virtual ~GeometryFactory(){}

public:

virtual Geometry* CreateGeometry() =0;

};

//---------------------------------------------------------------------------

/*

* 说明:C函数,用于获取GeometryFactory类的一个实例

*/

extern"C"

{

GeometryFactory* meGetGeometryFactoryInstance();

}

//===========================================================================

#endif

#ifndef __GEOMETRY_API_H__

#define __GEOMETRY_API_H__

//===========================================================================

class Geometry;

class GeometryFactory;

//---------------------------------------------------------------------------

/*

* 说明:几何对象类

*/

class Geometry

{

public:

Geometry(){}

virtual ~Geometry(){}

public:

virtual const char* GetType() = 0;

virtual void Release() = 0;

};

//---------------------------------------------------------------------------

/*

* 说明:几何对象工厂类

*/

class GeometryFactory

{

public:

GeometryFactory(){}

virtual ~GeometryFactory(){}

public:

virtual Geometry* CreateGeometry() = 0;

};

//---------------------------------------------------------------------------

/*

* 说明:C函数,用于获取GeometryFactory类的一个实例

*/

extern "C"

{

GeometryFactory* meGetGeometryFactoryInstance();

}

//===========================================================================

#endif

2、Geometry接口的实现类GeometryImpl

C++ geoemtryimpl.h代码

#ifndef __GEOMETRY_IMPL_H__

#define __GEOMETRY_IMPL_H__

#include"GeometryAPI.h"

class GeometryImpl : public Geometry

{

public:

GeometryImpl();

virtual ~GeometryImpl();

public:

virtual const char* GetType();

virtual void Release();

};

#endif

#ifndef __GEOMETRY_IMPL_H__

#define __GEOMETRY_IMPL_H__

#include "GeometryAPI.h"

class GeometryImpl : public Geometry

{

public:

GeometryImpl();

virtual ~GeometryImpl();

public:

virtual const char* GetType();

virtual void Release();

};

#endif

C++ geoemtryimpl.cpp代码

#include"GeometryImpl.h"

GeometryImpl::GeometryImpl()

{

}

GeometryImpl::~GeometryImpl()

{

}

const char* GeometryImpl::GetType()

{

return"GeometryImpl";

}

void GeometryImpl::Release()

{

delete this;

}

#include "GeometryImpl.h"

GeometryImpl::GeometryImpl()

{

}

GeometryImpl::~GeometryImpl()

{

}

const char* GeometryImpl::GetType()

{

return "GeometryImpl";

}

void GeometryImpl::Release()

{

delete this;

}

3、GeometryFactory接口的实现类GeometryFactoryImpl

C++ geometryfactoryimpl.h代码

#ifndef __GEOMETRY_FACTORY_IMPL_H__

#define __GEOMETRY_FACTORY_IMPL_H__

#include"GeometryAPI.h"

class GeometryFactoryImpl : public GeometryFactory

{

public:

GeometryFactoryImpl();

virtual ~GeometryFactoryImpl();

public:

virtual Geometry* CreateGeometry();

};

#endif

#ifndef __GEOMETRY_FACTORY_IMPL_H__

#define __GEOMETRY_FACTORY_IMPL_H__

#include "GeometryAPI.h"

class GeometryFactoryImpl : public GeometryFactory

{

public:

GeometryFactoryImpl();

virtual ~GeometryFactoryImpl();

public:

virtual Geometry* CreateGeometry();

};

#endif

此时的目录结构为:

include     存放.h文件

src         存放.cpp文件

4、编写makefile,编译动态库

C++ makefile代码

OBJS=GeometryFactoryImpl.o \

GeometryImpl.o

INCLUDE=-I../include

TARGET=libgemt.so

CPPFLAG=-shared -WI

CC=g++

LDLIB=

$(TARGET) : $(OBJS)

$(CC) $(CPPFLAG) $(INCLUDE) -o $(TARGET) $(OBJS) $(LDLIB)

$(OBJS) : %.o : %.cpp

$(CC) -c -fPIC $(INCLUDE) $

clean:

-rm -f $(OBJS)

install:

cp $(TARGET) /usr/lib

OBJS=GeometryFactoryImpl.o \

GeometryImpl.o

INCLUDE=-I../include

TARGET=libgemt.so

CPPFLAG=-shared -WI

CC=g++

LDLIB=

$(TARGET) : $(OBJS)

$(CC) $(CPPFLAG) $(INCLUDE) -o $(TARGET) $(OBJS) $(LDLIB)

$(OBJS) : %.o : %.cpp

$(CC) -c -fPIC $(INCLUDE) $< -o $@

clean:

-rm -f $(OBJS)

install:

cp $(TARGET) /usr/lib

将makefile文件放到src目录下,然后进入src目录,执行make命令,编译so库。

#make

编译完成后将生成libgemt.so动态库。

这个C++库用到了C++里面的虚基类,纯虚函数,继承,C函数,静态变量等概念。下面就看一下SWIG如何将这个C++的so库转换为Java接口。

二、利用SWIG将C++接口转换为Java接口

1、SWIG接口文件(.i)

SWIG需要编写一个后缀为.i的接口文件,把C++接口的定义写在.i文件中,也可以将C++的头文件include到.i文件中。这里我们将C++接口文件GeometryAPI.h include到.i文件中,文件名为gemt4j.i。

Gemt4j.i代码

/* File : gemt4j.i */

%module gemt4j

%{

#include"GeometryAPI.h"

%}

%include"GeometryAPI.h"

/* File : gemt4j.i */

%module gemt4j

%{

#include "GeometryAPI.h"

%}

%include "GeometryAPI.h"

module是模块名。SWIG将C函数通过Java的JNI转换为JAVA方法,这些方法都以静态方法的方式封装到一个与模块名同名的Java类中。

新建一个swig文件夹,将gemt4j.i文件存放到swig文件夹中。此时的目录结构为:

1、生成java类和wrap文件

编写好.i文件,就可以用swig生成java类和C++接口的wrap文件。

执行一下命令

#swig -c++ -java -package com.test -outdir ./ -I../include gemt4j.i

swig参数说明:

1)-c++ -java

告诉swig将C++接口转换为java接口。如果是将C接口转换为java接口,就不需要-c++,直接写 swig -java就可以。

2)-package

生成的java类的包的名称

3) -I

gemt4j.i中include的.h文件的路径

4)gemt4j.i

swig的.i文件

执行这条命令后,将在swig路径下生成几个文件

1)gemt4j_wrap.cxx

C++文件,包装器文件。它将C++类的方法转换为C的函数。

2)gemt4j.java

这是与刚才定义的module同名的一个类。

3)gemt4jJNI.java

打开这个文件可以看到,C++类的方法都转化为Java的静态方法。

4)其他与C++类同名的Java类

每一个C++类都被转化为与之对应的Java类,并且类名,方法明完全一样。

2、编译gemt4j_wrap.cxx文件为so库

1) java头文件

编译gemt4j_wrap.cxx需要用到jni的头文件jni.h

在我的机器上jdk安装在/opt/jdk1.5.0_20/下,

需要包行两个路径:

1)/opt/jdk1.5.0_20/include/

2) /opt/jdk1.5.0_20/include/linux/

2) libgemt.so库

还需要链接刚才编译好的libgemt.so库

编写makefile文件

Makefile代码

OBJS=gemt4j_wrap.o

INCLUDE=-I../include \

-I/opt/jdk1.5.0_20/include \

-I/opt/jdk1.5.0_20/include/linux

TARGET=libgemt4j.so

CPPFLAG=-shared -WI

CC=g++

LDLIB=-lgemt

$(TARGET) : $(OBJS)

$(CC) $(CPPFLAG) $(INCLUDE) -o $(TARGET) $(OBJS) $(LDLIB)

$(OBJS) : %.o : %.cxx

$(CC) -c -fPIC $(INCLUDE) $

clean:

-rm -f $(OBJS)

install:

cp $(TARGET) /usr/lib

OBJS=gemt4j_wrap.o

INCLUDE=-I../include \

-I/opt/jdk1.5.0_20/include \

-I/opt/jdk1.5.0_20/include/linux

TARGET=libgemt4j.so

CPPFLAG=-shared -WI

CC=g++

LDLIB=-lgemt

$(TARGET) : $(OBJS)

$(CC) $(CPPFLAG) $(INCLUDE) -o $(TARGET) $(OBJS) $(LDLIB)

$(OBJS) : %.o : %.cxx

$(CC) -c -fPIC $(INCLUDE) $< -o $@

clean:

-rm -f $(OBJS)

install:

cp $(TARGET) /usr/lib

生成libgemt4j.so库,jni就是通过这个库调用libgemt.so库中的类和方法的。

到现在为止,就通过SWIG将C++接口转换为Java接口。

三、使用SWIG生成的Java接口

1、编译Java文件

进入swig目录,SWIG生成的Java文件现在都在这里。

#javac *.java

生成class文件。

刚才我们设定的java包是com.test

创建com/test目录,将class文件移动到com/test目录下,然后打包

#cd swig

#tar -cvf gemt4j.jar ./com

生成gemt4j.jar包

2、将libgemt4j.so放到java的library path路径下。

可以通过下面的方式查一下java的library path路径

Java代码

classtest{

publicstaticvoidmain(String[] argv){

System.out.println(System.getProperty("java.library.path"));

}

}

class test{

public static void main(String[] argv){

System.out.println(System.getProperty("java.library.path"));

}

}

我这里的library pah为:/opt/jdk1.5.0_20/jre/lib/i386

把libgemt4j.so放到这个路径下即可。

3、编写java代码。

Java代码

importcom.test.*;

classtest{

static{

System.loadLibrary("gemt4j");

}

publicstaticvoidmain(String argv[]){

GeometryFactory factory =null;

factory = gemt4j.meGetGeometryFactoryInstance();

if(factory==null){

System.out.println("null GeometryFactory");

return;

}

Geometry geometry =null;

geometry = factory.CreateGeometry();

if(geometry==null){

System.out.println("null geometry");

return;

}

System.out.println(geometry.GetType());

geometry.Release();

}

}

import com.test.*;

class test{

static {

System.loadLibrary("gemt4j");

}

public static void main(String argv[]){

GeometryFactory factory = null;

factory = gemt4j.meGetGeometryFactoryInstance();

if(factory==null){

System.out.println("null GeometryFactory");

return;

}

Geometry geometry = null;

geometry = factory.CreateGeometry();

if(geometry==null){

System.out.println("null geometry");

return;

}

System.out.println(geometry.GetType());

geometry.Release();

}

}

说明:

System.loadLibrary("gemt4j");

用于装载libgemt4j.so库。

其他代码与普通的java无异。

编译java文件:

#javac -cp /home/hawk/code/swig/dll/java/gemt4j.jar test.java

执行test程序

#java -cp /home/hawk/code/swig/dll/java/gemt4j.jar:/home/hawk/code/swig/dll/java test

输出结果为:

GeometryImpl

可以看出,实现了Java调用C++类库libgemt.so

转自:

http://yingchao.iteye.com/blog/625797

swig c java gemt,利用 SWIG 转换 C/C++ 接口到 Java 接口相关推荐

  1. java怎么把毫秒转换成天数_关于java:如何将毫秒转换为“ hh:mm:ss”格式?

    我糊涂了. 绊倒这个线程后,我试图找出如何格式化具有hh:mm:ss格式的倒数计时器. 这是我的尝试- //hh:mm:ss String.format("%02d:%02d:%02d&qu ...

  2. java英文字符串大小写转换 必须使用_【Java基础】之字符串大小写转换不利用API....

    public class UpStr { static String str = "AbcDeFdDSfgdsadeADFSAFCfdsa"; public String tran ...

  3. java excel 导入 格式转换_【转】JAVA实现EXCEL的导入和导出(二)

    =================摘要===================== java如何操作Excel(数据导入导出)(转) jxl.jar,可以到http://sourceforge.net/ ...

  4. java字符实体_java转换 HTML字符实体,java特殊字符转义字符串(示例代码)

    编码转换(to Unicode) (程序代码来源于网络) Js版 test = "你好abc" str = "" for( i=0;    i { temp = ...

  5. JAVA的rotate怎么用,java如何利用rotate旋转图片_如何在Java中旋转图形

    I have drawn some Graphics in a JPanel, like circles, rectangles, etc. But I want to draw some Graph ...

  6. java jexl_利用Jexl实现数据库的计算公式在Java中执行

    public class JexlEngineUtils { public static BigDecimal evaluateExpression ( Map map, String[] eleme ...

  7. Java 格式转换:利用格式转换实现随机数生成随机 char 字母及 string 字母串

    文章目录 前言 一.char 型与数值型转换规则 二.随机数生成随机字母 三.随机数生成随机字母串 总结 前言 我们都知道在 Java 语言中有八种基本数据类型,而不同数据类型之间的转换你了解多少呢? ...

  8. Java中将inputstream输入流转换成byte[]字节数组

    Java中将inputstream输入流转换成byte[]字节数组 Java中的I/O机制都是基于数据流进行输入和输出的,将流转换成字节数组保存下来是数据流传输必不可少的一部分.转换的代码如下(在具体 ...

  9. java xmap_XML和Java Bean的互相转换攻略 【XMAP】

    XML和Java Bean的互相转换攻略  XML和Java Bean互相转换是一个很有用的功能,因为两者有着前后合作的关系,但解析的过程比较痛苦.下面介绍如何进行XML和Java Bean的互相转换 ...

最新文章

  1. 为什么电气自动化学历不高只能进厂?
  2. [UE4]C++实现动态加载的问题
  3. 1.2 Java系统流
  4. python中的列表生成式_生成器中的列表推导式
  5. Mapreduce的工作流程
  6. Python2 圆满落幕,Python 继续辉煌! | 原力计划
  7. python代码规范方面的书_你写的Python代码规范吗?
  8. 掘金小册:Git 原理详解和实用指南
  9. 深度学习——目前可用的3D人体数据集
  10. 【SpringBoot】添加Converter解析器中使用lambda表达式代替匿名内部类是启动报错: does the class parameterize those types?
  11. mbp touchbar设置_千万不要再买 TouchBar 的 MBP,教训深刻!
  12. 免费使用QQ邮箱“邮件短信通知”服务
  13. 【程序】Marvell 88W8686 WiFi模块(WM-G-MR-09)创建或连接热点,并使用lwip2.0.3建立http服务器(20180312版)
  14. 10.Go复合类型-切片
  15. sql2000服务器的注册码,安装完成后如何找回SQL Server实例安装时的序列号
  16. 【线代NumPy】第五章 - 行列式课后练习 | 伴随矩阵求逆 | Cramer公式求联立方程 | 简述并提供代码
  17. 电脑录制GIF动态图
  18. VMwar虚拟机安装winXP教程
  19. CC1101调试入门
  20. Gauss完全主元法(C#实现)——计算方法

热门文章

  1. 程序员的十个层次你属于哪一层?(知己知彼)
  2. 小空间大智慧 小户型装修地板选择
  3. Mac上好用的优质的软件合集
  4. Grunt 单独对css压缩并生成min.css文件
  5. 个人复盘和总结 2022——2023
  6. 魅族新系统android o,Flyme下月更新系统内核 魅族9款机型可升安卓7.0
  7. C++第3次实验(基础班)—选择结构程序设计(参考答案)-项目1:个人所得税计算器
  8. [转载] python反三角函数arctan_Python numpy.arctan() 使用实例
  9. VTK三维坐标点拾取
  10. 燕山大学教授「跨界」推翻爱因斯坦引争议