首页 > 代码库 > SWIG - 同Java的混合编程

SWIG - 同Java的混合编程

同Java的混合编程 - SWIG

最后更新日期:2014-04-20

阅读前提:推荐已经阅读《同C#的混合编程_SWIG入门》, 有Eclipse下编写JavaProject的经验。

作者: Kagula

环境:Windows 8.1 64bit(英文版)、VisualStudio 2013 Update1(英文版)、SWIG Win 3.0.0

、JDK 1.6.0_45 64bit、eclipse-jee-kepler-SR1-win32-x86_64

正文:

 

新建C++工程用于测试Java对它的调用

         [主菜单]->[NewProject]->[Visual C++]->[Win32]->[Win32 Project]给project起名为SWIG_Tutorial4后确认,ApplicationType选择DLL, Additional Options选择Empty Project其它默认。

    添加HelloWorldFromC.h文件,文件内容如下

#pragma once

/*
功能:演示Java对C++的基本调用
最后更新日期:2014-04-19
环境:Windows 8.1 64bit, Visual Studio 203 Update1, SWIG Win3.0.0
注意:对SWIG接口定义文件(i文件)来说生成C#接口同Java接口的最大区别是
调用SWIG.EXE程序一个用-csharp参数一个用-java参数,所以对C#的知识也适
用于这里。更复杂的调用形式,可以参考C++同C#混合编程方面的知识。
或则“...\swigwin-3.0.0\Examples\java”文件夹下面的例子,这里假设
你的SWIG运行目录在“D:\SDK\swigwin-3.0.0”路径下。
*/

/*测试Java对C++对象方法的调用*/
class HelloWorldFromC
{
public:
	int add(int a, int b);
};

/*测试Java对C++全局函数的调用*/
int multiply(int a, int b);


添加HelloWorldFromC.cpp文件,文件内容如下

#include "HelloWorldFromC.h"


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

int multiply(int a, int b)
{
	return a*b;
}


本演示程序的C++工程原代码文件共有两个,现在都已经建立好了。

         VisualStudio Win32 Project默认的是Win32模式,现在我们把它改为64位模式: 在[Solution Explorer]中选中项目,快捷键[Alt]+[Enter]打开项目属性页面。点击右上角[Configuration Manager...]按钮,打开ConfigurationManger对话框,在Active Solution Platform中选择<New...>,在“NewSolution Platform”对话框的Type or select the new platform中选择“x64”后OK。这样,当前项目的Platform就会变为“x64”,鼠标点击[Close]按钮后关闭ConfigurationManager对话框。

         因为我们用的是64位JDK,这样Eclipse建的默认JavaProject也是64bit的只能调用64位动态链接库,所以我们需要把C++工程的Platform从Win32改为x64。

 

 

现在新建Java工程,用于调用C++ 功能模块

打开Eclipse,[主菜单]->[File]->[New]->[Java Project]新建项目起名为SWIG_Tutorial4_Java。新建Class,起名为“MyJavaClass”。

 

编写SWIG接口

打开Visual Studio 中的SWIG_Tutorial4工程,为它添加SWIG_Tutorial4.i SWIG接口定义文件,源文件内容如下:

%module SWIG_Tutorial4 /* 这里要设置为C++项目名称 */

%{
/* i文件中(例如变量类型)使用到的头文件 */
#include "HelloWorldFromC.h"
%}

/* SWIG要解析的头文件 */
%include "HelloWorldFromC.h"


在[Solution Explorer]中选择[SWIG_Tutorial4.i]文件,[Alt]+[Enter]快捷方式,打开它的属性页。[Configuration Properties]->[General]->[Item Type]中,选择[CustomBuild Tool],点击OK后,再打开SWIG_Turotial4.i文件的属性页,[Configuration Properties]->[Custom BuildTool]->[General]->[Command Line]输入框中输入下面5行内容:

echo Invoking SWIG...

echo SWIG_HOME=$(SWIG_HOME)

echo on

$(SWIG_HOME)\swig.exe  -c++ -java -outdir  "D:\JWorkspace\SWIG_Tutorial4_Java\src"  "%(FullPath)"

echo off

这里假设" D:\JWorkspace\SWIG_Tutorial4_Java"是你刚才建的Java项目的存储路径。

[Configuration Properties]->[CustomBuild Tool]->[General]->[Outputs]输入框中输入下面一行内容:

%(Filename)_wrap.cxx

这样编译SWIG_Tutorial4.i文件就会调用SWIG.EXE程序,在当前C++项目路径下,生成SWIG_Tutorial4_wrap.cxx文件, 会在“D:\JWorkspace\SWIG_Tutorial4_Java\src”目录,生成java包装文件。

在Visual Studio中打开SWIG_Tutorial4项目的属性页,[Configuration Properties]->[Build Events]->[Post BuildEvent]->[Command Line]输入框中输入下面的三行内容

echo on

copy"$(OutDir)$(ProjectName).dll""D:\JWorkspace\SWIG_Tutorial4_Java"

echo off

在[Configuration Properties]->[Build Events]->[Post BuildEvent]->[Outputs]输入框中输入下面一行描述信息

Copy native dll to java run directory

 

这样当C++Build完成后会把DLL文件复制到"D:\JWorkspace\SWIG_Tutorial4_Java"路径下面。

编译SWIG_Tutorial4.i文件后,把生成的SWIG_Tutorial4_wrap.cxx文件加入到当前C++项目中, RebuildC++工程。

修改Java源代码并测试C++ DLL工程

打开Eclipse下的SWIG_Tutorial4_Java工程,刷新工程后,在[Package Explorer]中你可以看到SWIG.EXE为你生成的HelloWorldFromC.java、SWIG_Tutorial4.java、SWIG_Tutorial4JNI.java三个java文件(接口包装文件),修改MyJavaClass.java文件内容如下。

public class MyJavaClass {
	static {
		//这里填上C++工程的名称,同时也是C++写的DLL的名称
		System.loadLibrary("SWIG_Tutorial4");
	}
	
	public static void main(String[] args)
	{		
		/*
		打印libXXX.so文件的搜索路径
		System.out.println("java.library.path=" +
				System.getProperty("java.library.path"));
				*/
	
		HelloWorldFromC objC = new HelloWorldFromC(); 
		System.out.println("测试 C++对象方法调用=>"+objC.add(1, 2));
		System.out.println("测试 C++全局函数调用=>"+SWIG_Tutorial4.multiply(2, 3));
		
	}
}


现在运行Java文件就可以在Eclipse的Console窗口中看到运行结果。为了查看C++代码运行过程,你可以在Visual Studio中Attach Process到Java进程,单步跟踪C++写的动态链接库。

附:移植到CentOS上所用CMakeLists.txt文件的清单

#设置项目名称
PROJECT(SWIG_Tutorial4)

#要求CMake的最低版本为2.8
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

#添加头文件搜索路径
#下面两个是Cent OS下Java开发包的默认头文件路径
INCLUDE_DIRECTORIES(/usr/lib/jvm/java/include)
INCLUDE_DIRECTORIES(/usr/lib/jvm/java/include/linux)

#添加库文件搜索路径
#下面两个是Cent OS下Java开发包的默认库文件路径
LINK_DIRECTORIES(/usr/lib/jvm/java/lib)


#用于将当前目录下的所有源文件的名字保存在变量 DLL_SRC 中
AUX_SOURCE_DIRECTORY(. DLL_SRC)

#用于指定从一组源文件 source1 source2 … sourceN(在变量DLL_SRC中定义) 
#根据“SWIG_Tutorial4”名称编译出“libSWIG_Tutorial4.so”名称的动态链接库
#如果下面不加SHARED那编译出的是“libSWIG_Tutorial4.a”静态链接库
ADD_LIBRARY(SWIG_Tutorial4 SHARED ${DLL_SRC})


 

SWIG - 同Java的混合编程