Java通过JNA的方式调用dll库

在项目中需要用Java调用c++编写的dll库,以前了解过JNI的用法,后来发现JNA使用起来更加方便,缺点是不能在C++端调用Java端,但对于项目需求而言已经足够了。简单记录下JNA的用法。

JNA调用C的库函数输出“Hello world!”:

public class JnaTest {
	
	// This is the standard, stable way of mapping, which supports extensive
    // customization and mapping of Java to native types.
 
    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\n");
        for (int i=0;i < args.length;i++) {
            CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
        }
    }

}

JNA调用C函数的方式很简单,示例通过调用C语言中的printf函数实现输出“HelloWorld!”。

现在尝试调用自己编写的dll,在vs2013中编写dll,示例代码如下:

// AddDemo.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"


extern "C"_declspec(dllexport) int add(int a, int b);

int add(int a, int b) {
	return a + b;
}

需要注意的是,如果jdk的版本是32位的,则只能调用32的dll,若是64位的,则调用64位的dll。因为项目采用的Java是64位版本的,所以生成配置如下:

dll生成成功后即可通过Java调用:

public class DllTest {
	 
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)Native.loadLibrary("D:\\dll\\AddDemo.dll", CLibrary.class);
 
        int add(int a, int b);
    }
 
    public static void main(String[] args) {
        int sum = CLibrary.INSTANCE.add(3, 6);
 
        System.out.println(sum);
    }
}

定义接口加载dll库,在接口中声名要调用的函数名称,然后直接调用就可以了。

如果C中的函数用__stdcall声名过了,则接口需要继承StdCallLibrary,本项目中的dll功能是调用声卡来播放获取的音频数据,测试代码如下:

public class AudioRead {
	
	public interface CLibrary extends StdCallLibrary {
        CLibrary INSTANCE = (CLibrary)Native.loadLibrary("D:\\dll\\EVAL_Audio.dll", CLibrary.class);
        
        int WriteAudioDataParams();
        int WriteAudioData(double[] dOut);
        
    }
	
	public static void main(String[] args) {
		
		CLibrary.INSTANCE.WriteAudioDataParams();
		
		String path = "D:\\audioData";
		File file = new File(path);
		
		String[] filelist = file.list();
		
		for(int i=0;i<filelist.length;i++){
			
			 File readfile = new File(path + "\\" + filelist[i]);
			 double[] data = readData(readfile);
			 
			 CLibrary.INSTANCE.WriteAudioData(data);
			 
			 try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	private static double[] readData(File file){
		
		double[] data = null;
		
		try{
			
			Scanner sc = new Scanner(file);
		    List<Double> doubles = new ArrayList<Double>();
		    while (sc.hasNextDouble()) {
		      doubles.add(sc.nextDouble());
		    }
		    
		    data = new double[doubles.size()];
		    for(int i=0;i<doubles.size();i++){
		    	
		    	data[i] = doubles.get(i);
		    }

			
		}catch(Exception e){
			
			e.printStackTrace();
		}
		
		return data;
		
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值