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关键词,但是可以用虚基类来定义接口个,虚基类同样是只有定义,没有实现类,它的功能现放在继承类中实现。
#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
#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
#include "GeometryImpl.h"
GeometryImpl::GeometryImpl()
{
}
GeometryImpl::~GeometryImpl()
{
}
const char* GeometryImpl::GetType()
{
return "GeometryImpl";
}
void GeometryImpl::Release()
{
delete this;
}
3、GeometryFactory接口的实现类GeometryFactoryImpl
#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,编译动态库
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。
/* 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文件
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路径
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代码。
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
- 大小: 9 KB
- 大小: 3.8 KB
分享到:
相关推荐
使用Swig转换C++库到C#示例代码, 包含了示例的动态库和对应的代码 打包了应用程序 示例用法,提供参考
配置环境变量JAVA_BIN和JAVA_INCLUDE。比如: JAVA_BIN:C:\Program Files\Java\jdk-12.0.2\bin JAVA_INCLUDE:C:\Program Files\Java\jdk-12.0.2\include 进入Examples\java\simple目录,用VS2019打开example.dsp。...
NULL 博文链接:https://cherishlc.iteye.com/blog/1689224
C#利用SWIG调用C++的DLL示例程序,利用SWIG可以方便的在C#和C++之间架起沟通的桥梁。详见https://www.cnblogs.com/sinceret/p/14012099.html
SWIG is a compiler that takes C/C++ declarations and creates the wrappers needed to access those declarations from other languages including including Perl, Python, Tcl, Ruby, Guile, and Java....
swig 打包C/C++程序;供python调用。 本软件操作平台windows 10 Vs2017;python3.8; 主要讲述swig vs配置,测试用例。 主要包含常量,变量,指针,结构体定义及运用。
android studio 使用NDK和swig编译c++示例。使用swig可以自动化编译c++函数。比较方便。http://blog.csdn.net/qq_16064871
swig工具,C/C++到python, tcl 的接口
借助SWIG实现的CTP-java接口,测试程序见org.hraink.futures.jctp.test.Test。参考了csdn上的相关资料,分享出来供大家参考。
Python & C++ Comparisons Python C API SWIG
java调用dll java调用c,采用swig,官方实例,对官方代码中不能通过的地方做了修改和说明,有开发过程描述。
SWIG普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试C/C++或进行原型设计的工具。SWIG还能够导出XML或Lisp s-expressions格式的解析树。SWIG可以被自由使用,发布,修改用于商业或非商业中。
cmake_c++_python_swig
FrostWire的制造商为libtorrent提供的Swig Java接口。 用Java编写代码的乐趣来开发基于libtorrent的应用程序。 使用 所有平台都需要您至少使用2个.jar文件。 所述.jar与Java类- > jlibtorrent-wxyzjar和次级.jar...
用swig实现在python中使用c++的函数和类的很少的介绍的文章
go本身对c接口可以做到无缝链接,但对c++支持明显不足,本资源采用swig做桥接
将c++/c中的代码所实现的功能移植到别的语言上 c#调用c++ dome swig将c++程序生成dll供c#调用
对开发人员的一个常见要求是向脚本语言接口公开 C/C++ 代码,这正是 Simplified Wrapper and Interface Generator (SWIG) 的用武之地。SWIG 允许您向广泛的脚本语言公开 C/C++ 代码,包括 Ruby、Perl、Tcl 和 Python...
JavaCPP 提供了对 Java...相反,与cppyy为 Python 所做的事情类似,它利用了 Java 和 C++ 之间的语法和语义相似性。在底层,它使用 JNI,因此除了Android、Avian和RoboVM(指令)之外,它还适用于 Java SE 的所有实现。
SWIG软件开发工具,适用于将C\C++转换成C#、python等高级语言