同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})
备注
[1]如果你的Java项目类型是Web App,DLL库得放在System32目录下,否则加载动态链接库会不正确。
有时间测下其它java library path路径能不能放.