JAVA调用动态链接库

简介:

上一篇《JAVA本地接口(JNI)》中介绍了JAVA的JNI技术,通过JAVA自有的方式调用动态链接库,这一篇将继续为大家介绍使用其他方式调用动态链接库。
首先,我们编写一个用于测试的链接库

头文件 print.h

#ifdef DLL_IMPLEMENT  
   #define DLL_API __declspec(dllexport)  
#else  
   #define DLL_API __declspec(dllimport)  
#endif 

#ifndef _Included_PRINT
   #define _Included_PRINT
   #ifdef __cplusplus
      extern "C" {
   #endif
   DLL_API void print();
   DLL_API void print2(int i);
   DLL_API int print3(int i);

   #ifdef __cplusplus
      }
   #endif
#endif

源文件 print.c

#define DLL_IMPLEMENT 
#include <stdio.h>
#include "print.h"
DLL_API void print()
{
   printf("invoke print...");
}
DLL_API void print2(int i)
{
   printf("invoke print %d...", i);
}
DLL_API int print3(int i)
{
   return i;
}

使用c编译器对其进行编译:cl -LD print.c -Feprint.dll
然后我们将生成的print.dll放在系统的system32文件夹下,至此准备工作完成。

JNative

JNative是Java to native interface的缩写,使用JNative,我们可以很方便的调用动态链接库,使用示例如下:

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

public class JNativeTest
{
   public static void main(String[] args) throws Exception
   {
      // 加载动态链接库
      JNative print = new JNative("print.dll", "print");
      // 执行函数
      print.invoke();
      JNative print2 = new JNative("print.dll", "print2");
      // 设置函数形参
      print2.setParameter(0, 2);
      print2.invoke();
      JNative print3 = new JNative("print.dll", "print3");
      // 设置返回值类型
      print3.setRetVal(Type.INT);
      print3.setParameter(0, 3);
      print3.invoke();
      // 获得运行结果
      String result = print3.getRetVal();
      System.out.println("print3:" + result);
   }
}

下面再给出一个使用JNative获得系统时间的示例:

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.basicStructures.AbstractBasicData;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
import org.xvolks.jnative.util.Kernel32.SystemTime;

public class JNativeDemo extends AbstractBasicData<JNativeDemo>
{
   public short wYear;
   public short wMonth;
   public short wDayOfWeek;
   public short wDay;
   public short wHour;
   public short wMinute;
   public short wSecond;
   public short wMilliseconds;

   /**
    * 分配内存,并返回指针
    */
   public Pointer createPointer() throws NativeException
   {
      pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
      return pointer;
   }

   /**
    * 内存大小
    */
   public int getSizeOf()
   {
      return 8 * 2;
   }

   /**
    * 获取通过内存指针解析出结果
    */
   public JNativeDemo getValueFromPointer() throws NativeException
   {
      wYear = getNextShort();
      wMonth = getNextShort();
      wDayOfWeek = getNextShort();
      wDay = getNextShort();
      wHour = getNextShort();
      wMinute = getNextShort();
      wSecond = getNextShort();
      wMilliseconds = getNextShort();
      return this;
   }

   public JNativeDemo() throws NativeException
   {
      super(null);
      createPointer();
   }

   public String toString()
   {
      return wYear + "/" + wMonth + "/" + wDay + " at + " + wHour + ":"
            + wMinute + ":" + wSecond + ":" + wMilliseconds;
   }

   public static SystemTime GetSystemTime() throws NativeException,
         IllegalAccessException
   {
      // 创建对象
      JNative nGetSystemTime = new JNative("Kernel32.dll", "GetSystemTime");
      SystemTime systemTime = new SystemTime();
      // 设置参数
      nGetSystemTime.setParameter(0, systemTime.getPointer());
      nGetSystemTime.invoke();
      // 解析结构指针内容
      return systemTime.getValueFromPointer();
   }

   public static void main(String[] args) throws NativeException,
         IllegalAccessException
   {
      System.err.println(GetSystemTime());
   }
}

JNA

JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

使用示例:

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

public class JNADemo
{
   // 定义接口CLibrary,继承自com.sun.jna.Library
   public interface CLibrary extends Library
   {
      // 定义并初始化接口的静态变量
      CLibrary Instance = (CLibrary) Native
            .loadLibrary("print", CLibrary.class);

      // 函数声明
      void print();

      void print2(int i);

      int print3(int i);

   }

   public static void main(String[] args)
   {
      CLibrary.Instance.print();
      CLibrary.Instance.print2(2);
      System.out.println("print3:" + CLibrary.Instance.print3(3));
   }
}

JNative和JNA都可以实现对DLL的调用,但二者各有优缺点,需要根据实际情况选择。

目录
相关文章
|
5月前
|
Java 开发者
Java一分钟之-Quasar:协程库
【6月更文挑战第12天】Quasar是Java的高性能协程库,通过字节码增强实现轻量级并发模型——协程和通道,降低并发处理的复杂性和资源消耗。本文探讨了Quasar的常见问题,如内存泄漏、死锁和过度使用,提出相应避免策略,并提供了一个简单的协程间数据交换的代码示例。正确使用Quasar能提升程序性能和可维护性。
222 1
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
13天前
|
JSON JavaScript Java
在Java中处理JSON数据:Jackson与Gson库比较
本文介绍了JSON数据交换格式及其在Java中的应用,重点探讨了两个强大的JSON处理库——Jackson和Gson。文章详细讲解了Jackson库的核心功能,包括数据绑定、流式API和树模型,并通过示例演示了如何使用Jackson进行JSON解析和生成。最后,作者分享了一些实用的代码片段和使用技巧,帮助读者更好地理解和应用这些工具。
在Java中处理JSON数据:Jackson与Gson库比较
|
29天前
|
JSON Java 数据格式
Java Jackson-jr库使用介绍
Jackson-jr是专为资源受限环境设计的轻量级JSON处理库,适用于微服务、移动应用及嵌入式系统。它通过牺牲部分高级功能实现了更小体积和更快启动速度,非常适合对库大小敏感的项目。本文将介绍如何使用Jackson-jr进行JSON序列化与反序列化,并演示处理嵌套对象与数组的方法。此外,还介绍了自定义序列化与反序列化的技巧以及性能与功能的权衡。通过示例代码,展示了Jackson-jr在常见任务中的高效与灵活性。
20 0
|
2月前
|
数据采集 存储 前端开发
Java爬虫开发:Jsoup库在图片URL提取中的实战应用
Java爬虫开发:Jsoup库在图片URL提取中的实战应用
|
3月前
|
安全 Java
Java模拟生产者-消费者问题。生产者不断的往仓库中存放产品,消费者从仓库中消费产品。其中生产者和消费者都可以有若干个。在这里,生产者是一个线程,消费者是一个线程。仓库容量有限,只有库满时生产者不能存
该博客文章通过Java代码示例演示了生产者-消费者问题,其中生产者在仓库未满时生产产品,消费者在仓库有产品时消费产品,通过同步机制确保多线程环境下的线程安全和有效通信。
|
3月前
|
安全 Java API
Java 8 流库的魔法革命:Filter、Map、FlatMap 和 Optional 如何颠覆编程世界!
【8月更文挑战第29天】Java 8 的 Stream API 通过 Filter、Map、FlatMap 和 Optional 等操作,提供了高效、简洁的数据集合处理方式。Filter 用于筛选符合条件的元素;Map 对元素进行转换;FlatMap 将多个流扁平化合并;Optional 安全处理空值。这些操作结合使用,能够显著提升代码的可读性和简洁性,使数据处理更为高效和便捷。
81 0
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
|
5月前
|
存储 算法 搜索推荐
Java中的数组函数库及其使用技巧
Java中的数组函数库及其使用技巧
|
5月前
|
存储 并行计算 算法
深入解析Java并发库(JUC)中的Phaser:原理、应用与源码分析
深入解析Java并发库(JUC)中的Phaser:原理、应用与源码分析