首页 > 编程 > C++ > 正文

通过Swig封装JAVA Native Interface调用C++动态库

2019-11-08 19:46:49
字体:
来源:转载
供稿:网友

运行环境

Windows10 专业版 64位

JDK 1.8.0.121 64位

Eclipse Jee Neon

Visual Studio 2015 专业版

Swigwin3.0.12

先从Swig官网下载下最新版 Swig windows版,解压到任意目录.

我是解压在 D:/sdk/swigwin-3.0.12

设置环境变量 SWIG_HOME = D:/sdk/swigwin-3.0.12

PATH里多加个 %SWIG_HOME%

使我们在任意目录都能方便使用swig.exe

java 程序为 webapp,与控制台程序略有不同,网上例子大多为控制台程序调用C++动态库.使我一开始走了很多弯路.控制台的例子网上很多这里就不写了.

先上CPP代码:

在VS2015里创建控制台空项目,之所以要空项目,是省得到VS自动给你生成没用的 main函数,到时要删很烦.

在项目里新增类 SwigDemoToJava

SwigDemoToJava.h

/*SwigDemoToJava.h*/#PRagma onceclass SwigDemoToJava{public:	int SwigAdd(int i, int j);};SwigDemoToJava.cpp

#include "SwigDemoToJava.h"int SwigDemoToJava::SwigAdd(int i, int j){	return i + j;}很简单的一个类,测试用就实现一个整数加法.

然后在项目里新增Swig接口文件

SwigDemo.i

%module SwigDemo%{#include "SwigDemoToJava.h"%}%include "SwigDemoToJava.h"

这里解释一下,%module ,模块名 ,不能和C++类名相同,

Win+R运行 cmd.exe打开命令窗口

进入到 C++项目所在源代码目录,(此时swigdemo.i也应在此)

运行:  Swig -c++ -java -package com.myjavaproject.library -ourdir "e:/javaspace/myjavaproject/src/main/java/com/myjavaproject/library" swigdemo.i

当然,你也可以不指定 -outdir,

如果不指定-outdir,会在当前目录下生成4个文件 1个SwigDemo_wrap.cxx 和三个.java文件,手动把三个java文件copy到你的java项目中去.

在VS里把swigDemo_wrap.cxx加入到工程,然后重新编译,生成swigdemo.dll

把生成的dll复制到  java.library.path里列出来的任意目录..这里有点区别,在控制台java程序中java.library.path中列出的任意目录都可以放dll,JAVA程序都能调用到dll

但是如果是webApp,把DLL放在有些目录就不能调用.比如我之前把dll放在C:/Program Files/Java/jre1.8.0_121/bin/server 下(该目录也是 library.path)

控制台程序可以正常调用DLL,而webApp则能loadlibrary,但一new对像就异常.

我个人猜测,可能是控制台APP直接创建新JVM线程,而webApp依靠于Tomcat的原因,具体什么原因不明,以后有空再研究了.

转回正题.编写JAVA程序.

我原来有个JAVA项目,项目名我这里暂时用myjavaproject代替.

为了简单,我直接在控制器里调用C++动态库了,

直接代码:

package com.myjavaproject.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.myjavaproject.controller.BaseController;import com.myjavaproject.library.SwigDemoToJava;;@Controller@RequestMapping("/NativeDemo")public class NativeDemoController extends BaseController {	@RequestMapping("/demo1.do")	@ResponseBody	public String demo1(String param1,String param2) {		try {			System.loadLibrary("SwigDemo");			SwigDemoToJava sd1 = new SwigDemoToJava();			return "SwigDemo is:"			+String.valueOf(sd1.SwigAdd(Integer.parseInt(param1),Integer.parseInt(param2)));		} catch (Exception e) {			return e.getMessage();		}	}}保存,运行

在浏览器里输入http://localhost:8080/myjavaproject/NativeDemo/demo1.do?param1=11&param2=22

返回:

SwigDemo is:33

成功调用C++动态库里的SwigAdd成员函数.

注意事项:

1.Swig接口文件里%module 模块名,不能同C++类名一样

2.在WebApp里,不是所有的library path都能放动态库.我最后是把DLL直接放在C:/Windows/System32 下面,下次有空再研究一下怎么放在WebApp指定目录....

3.在swig命令里最好指定package.并放到项目的相应目录下.

4.还没想到....

最后留下此笔记,以备未来哪天忘记了方便查阅


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选