如何通过JNA调用Linux系统自带的libc.so动态库的printf函数,现在再通过一个简单的例子介绍如何通过JNA调用自己编写的C动态库并在动态库中调用Java的函数(回调)。
编写C代码:
#include <stdio.h>
static int (*AddByCallback)(int a,int b)=NULL;
void RegisterAdd(int (*callback)(int,int))
{
AddByCallback=callback;
}
void DoAddByCallback(int a,int b)
{
int res;
if(AddByCallback==NULL)
{
printf("error: please register the Add function first!\n");
return;
}
res=AddByCallback(a,b);
printf("Java execute add: %d+%d=%d\n",a,b,res);
}
2.编译C代码:
gdyt:/home/yc/soft/test # ll
total 36
-rwxr-xr-x 1 root root 5812 Dec 22 23:14 libtest.so
-rw-r--r-- 1 root root 61 Dec 22 23:14 test.c
-rw-r--r-- 1 root root 367 Dec 22 23:17 testcallback.c
-rwxr-xr-x 1 root root 19584 Dec 22 23:14 testlib.c
gdyt:/home/yc/soft/test # gcc -fPIC -shared testcallback.c -o libtestcallback.so
gdyt:/home/yc/soft/test # ll
total 48
-rwxr-xr-x 1 root root 5812 Dec 22 23:14 libtest.so
-rwxr-xr-x 1 root root 9887 Dec 22 23:19 libtestcallback.so
-rw-r--r-- 1 root root 61 Dec 22 23:14 test.c
-rw-r--r-- 1 root root 367 Dec 22 23:17 testcallback.c
-rwxr-xr-x 1 root root 19584 Dec 22 23:14 testlib.c
3.查看so并拷贝到lib目录
查看so的依赖关系
gdyt:/home/yc/soft/test # ldd libtestcallback.so
linux-vdso.so.1 => (0x00007fff24dfe000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc91c7ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc91cd78000)
添加相关的连接
gdyt:/home/yc/soft/test # ln -s libtestcallback.so libJnaCbApi.so.6
gdyt:/home/yc/soft/test # ll
total 48
lrwxrwxrwx 1 root root 18 Dec 22 23:24 libJnaCbApi.so.6 -> libtestcallback.so
-rwxr-xr-x 1 root root 5812 Dec 22 23:14 libtest.so
-rwxr-xr-x 1 root root 9887 Dec 22 23:19 libtestcallback.so
-rw-r--r-- 1 root root 61 Dec 22 23:14 test.c
-rw-r--r-- 1 root root 367 Dec 22 23:17 testcallback.c
-rwxr-xr-x 1 root root 19584 Dec 22 23:14 testlib.c
查看相关的依赖关系
gdyt:/home/yc/soft/test # ldd libJnaCbApi.so.6
linux-vdso.so.1 => (0x00007fffe95ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb9e101d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb9e15ab000)
4.拷贝到lib目录
gdyt:/home/yc/soft/test # cp libtestcallback.so lib/
5.编写Java代码:
package com.etrip;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
*
* @Title: TODO
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:
* @Date:2012-12-22
* @author longgangbai
* @version 1.0
*/
public class JNACallback {
// 定义接口CLibrary,继承自com.sun.jna.Library
public interface CLibrary extends Library {
// 定义接口JavaCallbackAdd,继承自com.sun.jna.Callback
interface JavaCallbackAdd extends Callback {
int CallbackAdd(int a, int b);
}
// 动态库的函数声明
void RegisterAdd(JavaCallbackAdd callback);
void DoAddByCallback(int a, int b);
}
public static void main(String[] args) {
// 接口实例化并初始化实例
CLibrary lib = (CLibrary) Native
.loadLibrary("JnaCbApi", CLibrary.class);
if(lib!=null){
System.out.println("JnaCbApi加载成功...");
}
CLibrary.JavaCallbackAdd callback = new CLibrary.JavaCallbackAdd() {
// 实现CallbackAdd函数
public int CallbackAdd(int a, int b) {
return a + b;
}
};
// 调用动态库的函数
lib.RegisterAdd(callback);
// 由动态库执行CallbackAdd回调函数
lib.DoAddByCallback(1, 2);
}
}
6.测试