代码改变世界

JNative入门使用--简化windows和linux调用DLL的过程

2012-02-16 10:56  会被淹死的鱼  阅读(8197)  评论(0编辑  收藏  举报

JNative官方主页:

http://jnative.free.fr/SPIP-v1-8-3/

http://sourceforge.net/projects/jnative/

JNative是可以方便地调用DLL, 相对于JNI来说, 非常的方便, 使用和学习也是很简单. 现在该项目已经很久未更新了. 目前最新版是1.4 RC3.

注意事项: JNative只支持32位的JDK, 64位的系统需要安装32位的JDK来使用JNative, 否则或报错:

java.lang.IllegalStateException: JNative library not loaded, sorry !

我个人觉得, 错误原因是JNative本身需要加载一个JNativeCpp.dll, 这个dll是在32位系统下编译的, 64位JDK加载的时候, 会导致加载不成功.

1.4 RC3的JNative.jar中的lib-bin中自带了JNativeCpp.dll, 所以不需要再为JNative.jar配置JNativeCpp.dll.

使用eclipse, 直接添加JNative.jar, 使用32位的JDK就可以使用JNative了.

使用示例: http://www.iteye.com/topic/284818

1. 编译自己的dll

test.h 头文件(考虑了GCC和MS VC两种编译器)

#ifndef _TEST_H__  
#define _TEST_H__

#ifdef _MSC_VER
_declspec(dllexport) int add(int a,int b);
#endif

#ifdef __GNUC__
int add(int a,int b);
#endif

#endif

test.c

#include <stdio.h>
#include "test.h"

int add(int a, int b)
{
printf("dll function add() called\n");
return (a + b);
}

这里使用MinGW来进行编译, 需要先安装MinGW

gcc -Wall -shared test.c -o test.dll 

如果使用微软的编译器cl的话, 编译命令为

cl test.c /link /out:test.dll /dll /OPT:NOWIN98 /machine:x86

这样就获得了test.dll文件

2. 下面使用JNative来调用自己的dll中的函数add

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;

// 使用32位jdk
public class Test {
public static int nativeAdd(int a, int b) throws NativeException, IllegalAccessException {
JNative n = null;
n = new JNative("test.dll", "add");
n.setRetVal(Type.INT);
n.setParameter(0, a);
n.setParameter(1, b);
n.invoke();
System.out.println("返回: " + n.getRetVal());
return Integer.parseInt(n.getRetVal());
}

public static void main(String[] args) {
try {
nativeAdd(1, 2);
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

test.dll放在eclipse工程根目录下即可.

测试结果如下:

返回: 3
dll function add() called

说明:

上面给的链接中的例子, 有try...finally..., 在finally中有如下代码

if (n != null)  
n.dispose();

根据1.4 RC3的源代码中, 我们可以看到整个方法已经被注释.

 /**
* <p>
* This method does nothing!
* </p>
*
@deprecated this method does nothing

*
@exception NativeException
*
@exception IllegalAccessException
* if <code>dispose()</code> have already been called.
*
*/
@Deprecated
public final void dispose() throws NativeException, IllegalAccessException
{
/*
throwClosed();

synchronized (mLibs)
{
LibDesc libDesc = getLibDesc(mDllName);
libDesc.numHolders--;
if(libDesc.numHolders == 0)
{
nDispose(mJNativeHModule);
mIsClosed = true;
mLibs.remove(mDllName);
}
}
*/
}


总结

使用JNative可以方便地调用已有的dll, 可以提高系统的性能, 方便了跨语言的调用, JNative本省支持windows和linux, 也增强了自身的移植性, JNative本身的想法和出发点都是非常好的, 使用更加Java的方式来调用dll.

这个类库已经很久未更新, 所以使用的时候还是要慎重考虑.

本文只是简单的介绍, 还有很多不全面的地方, 欢迎拍砖!