`
marsprj
  • 浏览: 65383 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用SWIG转换C++接口到Java接口

阅读更多
    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
分享到:
评论
1 楼 lampard1985 2016-10-20  
你好 这个makefile 执行报错,可以知道更正下吗

相关推荐

    swig--在java、C#中调用c++写的DLL(以vs2012配置为例)

    总结一下,本教程主要介绍了如何使用SWIG在Java和C#中调用C++编写的DLL,涉及到的知识点包括:SWIG工具的使用,C++ DLL的创建,接口文件的编写,以及Java的JNI和C#的DllImport特性。这些步骤对于跨语言编程和利用...

    使用swig将C代码转为JAVA接口的例子(Win10平台)

    配置环境变量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。...

    C++头文件转JAVA JNA接口类

    本篇文章将详细介绍如何将C++的头文件转换为Java的JNA接口类,以便于Java程序调用C++ DLL中的接口。 首先,我们需要理解JNA的工作原理。JNA通过定义Java接口来映射C/C++函数,并在运行时动态加载本地库,实现调用。...

    swig实例java调用c

    `Swig`(Simplified Wrapper and Interface Generator)是一个强大的工具,它允许我们创建接口,使得Java等高级语言能够调用C或C++编写的库。本实例主要讲解如何使用Swig来实现Java调用C代码,并通过DLL动态链接库...

    Java和c++互相回调的例子

    9. **性能考虑**: 虽然JNI提供了Java和C++的互操作性,但频繁的Java到C++的调用可能会引入额外的性能开销,因为涉及到了Java对象到本地数据的转换。因此,在设计系统时,应谨慎考虑这些调用的频率和复杂性。 10. **...

    SWIG v3.0.6.zip

    SWIG的工作原理是通过解析C或C++头文件,自动生成必要的接口代码,从而让这些低级语言的库能够在高级语言环境中无缝使用。 SWIG的核心功能在于它的接口描述语言(IDL),这是一种简单的文本格式,允许开发者定义...

    cygwin+swig生成Android库并使用的例子

    在本教程中,我们将深入探讨如何使用Cygwin和SWIG工具将C/C++代码转换为Android兼容的库,并在Android...这个过程涉及到接口文件的编写、SWIG命令的执行、C++代码的编译以及Android项目的集成,每一步都是成功的关键。

    SWIG是一种软件开发工具,可将用C和C++编写的程序与各种高级编程语言连接起来_C++_下载.zip

    SWIG的主要目标是简化接口的创建,使得C和C++库可以被Python、Perl、Ruby、Java、Tcl、JavaScript等脚本语言调用,甚至包括MATLAB和Octave这样的科学计算环境。通过使用SWIG,开发者可以充分利用现有C/C++库的性能...

    swig4.1.1linux版+windows版

    3. **类型转换**:SWIG处理不同语言间的数据类型转换,例如C++的对象到Python的类。 4. **内存管理**:自动处理跨语言间的内存管理,避免内存泄漏。 5. **预处理器**:SWIG有自己的预处理器,可以处理宏和其他复杂的...

    swig-4.0.1.tar.gz

    SWIG(Simplified Wrapper and Interface Generator)是一款强大的工具,用于将C和C++代码自动封装成其他编程语言的接口,如Python、Java、Perl、PHP等。`swig-4.0.1.tar.gz`是一个包含SWIG 4.0.1版本源代码的压缩包...

    swig-3.0.12.tar

    SWIG(Simplified Wrapper and Interface Generator)是一款强大的工具,用于将C和C++代码自动封装成其他编程语言的接口,比如Python、Java、Perl、PHP等。SWIG 3.0.12是该工具的一个特定版本,它包含了对各种语言...

    swig-2.0.10 .tar.gz

    SWIG(Simplified Wrapper and Interface Generator)是一款强大的工具,用于将C和C++代码与多种高级语言(如Python、Perl、Java、Ruby等)连接起来。`swig-2.0.10.tar.gz` 是SWIG的一个版本,具体是2.0.10版的源码...

    swig-2.0.6.tar.gz_swig-2.0.1.tar.gz

    SWIG(Simplified Wrapper and Interface Generator)是一款强大的工具,用于将C和C++代码自动绑定到多种脚本语言,如Python、Perl、Tcl、Java等。标题中的"swig-2.0.6.tar.gz_swig-2.0.1.tar.gz"表明这是两个不同...

    swig使用手册

    SWIG不仅支持C/C++的基本语法,还覆盖了包括结构体、枚举、指针等在内的复杂特性,使得C/C++代码的功能可以完整地移植到脚本语言中。同时,SWIG采用非侵入式设计,即原始的C/C++代码无需修改即可被封装,这保证了...

    Java调用C++类库--JNI

    注意,JNI接口设计复杂,涉及到内存管理、异常处理以及类型转换等问题。此外,为了保证跨平台兼容性,开发过程中可能需要对不同操作系统(如Windows、Linux、Mac OS等)的库文件管理和加载方式有所了解。 在实际...

    swig-2.0.7.tar.gz

    SWIG是一个强大的工具,主要用于创建程序接口,它可以将C和C++代码与多种高级语言如Python、Perl、Java、Ruby、Tcl、PHP、JavaScript等相连接。它的主要用途是简化创建这些脚本语言的绑定,使得C或C++库可以轻松地在...

    swigwin-3.0.10.zip

    SWIG(Simplified Wrapper and Interface Generator)是一款强大的工具,用于将C和C++代码自动封装成其他编程语言的接口,比如Python、Java、Perl、Tcl等。在本压缩包"swigwin-3.0.10.zip"中,包含的是SWIG的Windows...

    基于SWIG的Python仪器驱动封装技术.pdf

    为了解决这一问题,SWIG(Simple Wrapper and Interface Generator)作为一款跨语言接口转换工具,能够有效地将C、C++等静态编译型语言与Python等动态脚本语言进行接口转换,从而弥补Python在仪器编程方面的不足。...

    多语言粘合工具swig源代码

    - **接口自动生成**:SWIG可以生成面向对象的语言接口,例如在Python中创建C++类的子类。 - **文档生成**:SWIG可以从源代码注释生成文档,方便开发者理解和使用。 - **模块管理**:SWIG支持模块化设计,可以将库...

    swigwin-4.1.1.zip

    这极大地简化了跨语言交互,特别是在需要编写多语言接口或者希望利用C/C++高效性能的同时享受高级语言便利性的情况下。 SWIG的使用流程通常包括以下几个步骤: 1. **编写接口文件**:在SWIG接口文件(.i文件)中,...

Global site tag (gtag.js) - Google Analytics