JAVA中利用JNA调用dll或so

JNA中使用不同的接口来映射C中的结构体,指针,函数指针等概念。所以下面列举一个很经典的例子。

调用DLL 

1. 在VS中创建一个DLL项目。

  选择创建Win32 Console Application,然后选择DLL

     

2. 编写Demo 

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
#define MYLIB extern "C" __declspec(dllexport)
extern "C"{
	MYLIB typedef void(*OpenFun)(const char*, int);
	OpenFun openfun=NULL;
	MYLIB void init(OpenFun fun){
		cout << "init fun" << endl;
		openfun = *fun;
	}
	MYLIB void test(){
		if (openfun == NULL)
			cout << "openfun is null" << endl;
		(*openfun)("test", 1);

	}
	

}

  解释: 以上代码声明一个函数指针类型 OpenFun ,然后定义两个函数init和test  其中init函数中初始化openfun ,然后在test中调用openfun函数。其中MYLIB 是一个宏,为了将函数指针和函数进行导出。

3. 编译DLL, 编译为x64

    

4.  编写JAVA代码,并导入DLL文件(DLL文件放在工程bin目录下)

//Clib.java

package com.java;

import com.sun.jna.Callback;
import com.sun.jna.Library;

public interface Clib extends Library{
	public interface OpenFun extends Callback{
		void callIn(String filename,int i);
	}
	void init(OpenFun openfun);
	void test();
	
}
//HelloTest.java

package com.java;
import com.sun.jna.Native;
public class HelloTest {
  public static void main(String[] args) {
	Clib lib=(Clib) Native.loadLibrary("Mylib", Clib.class);
	lib.init(new Clib.OpenFun() {
		
		public void callIn(String filename, int i) {
			// TODO Auto-generated method stub
			System.out.println("callback called");
			System.out.println(filename);
		}
	});
	lib.test();
}
}

解释: Clib.java 主要就是完成和C代码的一个映射,用继承callback 接口映射 函数指针,其中继承callback接口的名称要跟C代码中函数指针类型一致,然后接口中定义一个函数,用来实现函数内容,其中函数参数需要跟C代码中函数参数一致。函数名称可以自定义。

 HelloTest 中主要完成加载动态库,其中Native.loadLibrary会在指定的位置加载Mylib.dll或libMylib.so ,根据Java程序跑在windows还是linux上。然后调用到C代码中init函数来初始化函数指针,其中这个函数指针对应的函数在java中实现。然后调用test。

 运行结果:

  

调用so文件

   生成动态库

//Mylib.c

#include <stdlib.h>
#include <stdio.h>

typedef void(*OpenFun)(const char*, int);
OpenFun openfun=NULL;

void init(OpenFun fun)
{
	openfun = *fun;
}
void test()
{
	if (openfun == NULL)
		printf("openfun is null");
	(*openfun)("test", 1);

}

  在linux上通过 gcc Mylib.c -fPIC -shared -o libMylib.so

  java代码依然使用上述的代码,不过在linux上使用java命令行来编译。 需要将Clib.java 和HelloTest.java中package com.java 删除掉。 

如何在linux上安装jdk以及配置环境变量参考以下文章: https://www.cnblogs.com/panzhaohui/p/6306675.html

然后将jna对象的jar拷贝到linux机器上。我们目录如下图所示,将libMylib.so jna-4.0.0.jar 以及java源码放在同一个目录,当然也可以将libMylib.so 动态库按照linux上查找动态库的路径 放置在某一处可以被查找即可。

   

1. 编译java

     javac -classpath jna-4.0.0.jar Clib.java HelloTest.java

2. 执行java程序

   java -classpath .:jna-4.0.0.jar HelloTest

  

这里我们可以看到成功调用了so动态库。 

  参考的文章:https://www.cnblogs.com/zhanglinfan/articles/5078548.html

                        https://www.cnblogs.com/chaofn/p/9939761.html

  linux上动态库查找的路径和修改:https://blog.csdn.net/f110300641/article/details/82657972

    

猜你喜欢

转载自blog.csdn.net/sinat_33822516/article/details/100166676
今日推荐