【CSDN常见问题解答】使用JNA调用Windows动态库

Java中调用Windows平台的动态库一般会使用JNI(Java Native Interface)还有JNA(Java Native Access)。

首先解释下为什么我会选用JNA,一句话来说就是使用简单。

我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的。 如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另外使用C语言写一个.dll/.so共享库,使用SUN规定的数据结构替代C语言的数据结构,调用已有的 dll/so中公布的函数。然后再在Java中载入这个适配器dll/so,再编写Java  native函数作为dll中函数的代理。

经过2个繁琐的步骤才能在Java中调用本地代码。因此,很少有Java程序员愿意编写调用dll/.so库中的原生函数的java程序。这也使Java语言在客户端上乏善可陈。可以说JNI是Java的一大弱点!所以我们就选择JNA来写几个简单的demo。

JNA在GitHub上的地址:https://github.com/twall/jna

需要jar包,到lib文件夹里面去下载。

下面我们开始使用JNA。

第一个例子:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

public class HelloWorld {
	public interface CLibrary extends Library {
		CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
		void printf(String format, Object... args);
	}

	public static void main(String[] args) {
		CLibrary.INSTANCE.printf("Hello World, ");
		for (int i = 0; i < args.length; i++) {
			CLibrary.INSTANCE.printf("Argument %d: %s, ", i, args[i]);
		}
	}
}

运行上面的代码,我给main函数传递了3个参数1 2 3,打印如下:

Hello World, Argument 0: 1, Argument 1: 2, Argument 2: 3, 

但是,请注意,这个程序实际上是使用msvcrt.dll这个C运行时库中的printf函数打印出上面这些字符的。是不是很简单,不需要写一行C代码,就可以直接在Java中调用外部动态链接库中的函数!

 

第二个例子:

上面那个例子使用了操作系统自带的动态链接库,现在我们再自己写一个动态链接库试试。

1,在VS中选择C++语言,然后选择创建一个Win32程序。选择dll类型。
2,发布的C函数是:


#define MYLIBAPI extern  "C"    __declspec(dllexport ) 
MYLIBAPIvoid say(wchar_t* pValue);

这个函数的实现是:

void say(wchar_t* pValue){
    std::wcout.imbue(std::locale("chs"));
    std::wcout<<L"他说:"<<pValue<<std::endl;
}

它需要传入一个Unicode编码的字符数组。然后在控制台上打印出一段中文字符。

3,生成dll(TestDll1.dll)。然后把生成的dll文件复制到Eclipse项目中,放在项目下面。

4,然后编写下面的类:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.WString;

public class TestDll1Service {

        public interface TestDll1 extends Library {
                  /**

                   * 当前路径是在项目下,而不是bin输出目录下。

                   */

                  TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class);
                  public void say(WString value);

        }

        public TestDll1Service() {

        }

 

        /**

         * @param args

         */

        public static void main(String[] args) {
                  TestDll1.INSTANCE.say(new WString("Hello World!"));
                  System.out.println("你好,我是来测试的!");
        }

}

5,执行这个Java类。可以看到控制台下如下输出:

他说: Hello World!

你好,我是来测试的!

6,上面一行是C语言使用C++的std::wcout输出的。 下面一行是Java语言输出的。





准备工作: 1.编译JnativeCpp 2.将编译出来的libJNativeCpp.so,拷贝到/usr/lib/,同时执行chmod 555 libJNativeCpp.so 测试过程简介 1.c测试库libtest.so 环境:ubuntu10.4下 语言:c 编译库名称为:libtest.so 涉及文件:so_test.h test_a.c test_b.c test_c.c 终端执行命令:$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so 将编译得到到libtest.so拷贝到/usr/lib/,同时执行chmod 555 libtest.so 2.qt测试库libmylib.so 环境:ubuntu10.4下 语言:c 编译工具:qt Creator 编译库名称为:libmylib.so 将编译得到到libmylib.so拷贝到/usr/lib/,同时执行chmod 555 libmylib.so 3.编译环境安装 a.安装jdk 1.6 b.安装netBeans 6.8 c.创建javaApp工程 d.JNative.jar添加到工程中 e.参考如下代码,编写后编译执行,并运行 import org.xvolks.jnative.JNative; import org.xvolks.jnative.Type; import org.xvolks.jnative.exceptions.NativeException; public class Main { public static void main(String[] args) throws NativeException, IllegalAccessException{ //纯c写到动态库 JNative clib = new JNative("libtest.so", "test_a"); //调用libtest.so下到test_a函数 clib.setRetVal(Type.STRING); //设置此函数的返回值 clib.invoke(); //函数执行 System.out.println(clib.getRetVal());//输出函数返回结果 //qt写到动态库 //以下部分使用qt编译到so,注意在函数声明前加 extern "C" //如extern "C" const char* getLocalHost(); JNative getstring = new JNative("libmylib.so", "getstring"); getstring.setRetVal(Type.STRING); getstring.invoke(); System.out.println(getstring.getRetVal()); } } 4.输出结果 this is in test_a... getstring hello .....
### 回答1: JNA(Java Native Access)是一个Java开发平台上的库,可以用来访问本地的动态链接库(DLL)。在CSDNCSDN是一个面向IT技术开发者和创客的社区平台)上,你可以找到并下载一些使用JNA的DLL库。 在CSDN上有许多开发者分享了自己编写的DLL库,这些库可以通过JNA被Java程序所调用。你可以在CSDN的下载中心或者在线论坛中搜索相关的关键词,如“JNA DLL库”、“Java调用本地库”等,以找到你需要的DLL库。 下载DLL库时,你需要选择与你所使用的操作系统和JVM相对应的版本。确保下载的DLL库与你的开发环境兼容,避免出现问题。一般来说,下载的DLL库文件是以.dll为后缀的,你可以将其放置在你的项目中,并在Java代码中通过JNA进行加载和调用JNA提供了一些API和类,如Native类和Library接口,用于加载和调用本地DLL库。你可以通过这些类来实现与本地库的交互,调用其中的函数和方法,实现特定的功能。 总之,在CSDN上可以找到并下载到一些使用JNA的DLL库。这些库可以帮助你在Java应用程序中实现与本地库的互操作。记得在使用前进行适当的测试和验证,确保库与你的开发环境兼容并满足你的需求。 ### 回答2: JNA(Java Native Access)是一个开源的Java程序库,可以用来在Java程序中调用本地的动态链接库(DLL)。 在CSDN上可以下载很多已经编写好的DLL库文件。CSDN是一个IT技术交流平台,其中有很多开发者分享自己编写的代码和库文件。通常,我们可以通过CSDN搜索或浏览相关的DLL库文件并进行免费或付费下载。 如果想要使用JNA调用某个DLL库,首先需要在CSDN上搜索并找到符合需求的库文件。下载并保存这个DLL库文件到本地的某个目录下。然后,在Java程序中使用JNA的API,根据DLL库的具体名称和路径,加载这个DLL库文件。接着,我们可以通过JNA提供的方法调用这个DLL库文件中的函数、变量等。 因为JNA简化了Java调用本地代码的复杂性,所以使用JNA可以方便地将DLL库文件集成到Java程序中。而在CSDN上下载DLL库文件,可以节省我们编写这些库文件的时间和精力,可以直接使用他人编写好的代码来实现特定的功能,加快开发过程。 总之,JNA可用于在Java程序中调用本地的动态链接库(DLL),而我们可以在CSDN上下载到很多编写好的DLL库文件,方便我们在Java程序中使用
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值