JNA编程之三:调用自定义的C动态库并支持回调

来源:互联网 发布:拍卖系统数据库设计 编辑:程序博客网 时间:2024/06/03 02:37
在文章《JNA编程之一:入门》中已经介绍了如何通过JNA调用Linux系统自带的libc.so动态库的printf函数,现在再通过一个简单的例子介绍如何通过JNA调用自己编写的C动态库并在动态库中调用Java的函数(回调)。

0. 备注:
操作系统:Ubuntu-10.10
工作用户:root
JDK版本:1.6&1.7
开发环境:eclipse

1. 创建C动态库工程JnaCbApi
代码如下:
#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);
}
说明:
1)动态库JnaCbApi的主要功能是由外部应用程序注册一个回调函数,然后调用该回调函数进行加法运算。因此外部应用程序的回调函数必须实现两个整数的加法运算。
2)该动态库只留出了两个接口函数RegisterAdd和DoAddByCallback。其中RegisterAdd用于注册一个Java的回调函数,而DoAddByCallback则调用Java注册的回调函数进行加法运算,并将运算结果打印出来。
3)编译链接生成 libJnaCbApi.so动态库文件。

2. 往Java工程JnaTest中添加新代码
注:JnaTest工程是在《JNA编程之一:入门》一文中创建的。
2.1 往JnaTest工程中添加新的源文件JnaCallback.java,并在文件中输入如下代码:
package myjava.jna.test;

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

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);
    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);
    }
}

2.2 复制动态库文件libJnaCbApi.so到JnaTest工程根目录下。

2.3 编译JnaCallback.java文件并运行,结果如图2-1所示。
JNA编程之三:调用自定义的C动态库并支持回调 - Jim - Jim Liang
图2-1:JnaCallback运行结果
提示:如果在你的Linux环境下JnaCallback程序无法加载libJnaCbApi.so动态库,通常有两种解决办法。
1)将libJnaCbApi.so复制到系统的动态库目录,如 /lib 或 /usr/lib。
2)修改/etc/profile文件,在文件末尾添加命令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./,保存后注销或重启系统即可。添加这句命令的意思是让系统支持从“当前目录”加载动态库。

【参考】:
1)https://github.com/twall/jna/blob/master/www/CallbacksAndClosures.md

2)http://hpfgc.blog.163.com/blog/static/14799557201011814356333/

转自:http://blog.163.com/ljf_gzhu/blog/static/131553440201242115411403/

原创粉丝点击