`
longgangbai
  • 浏览: 7338818 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

阅读更多

        如何通过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);
}

 

 

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

 

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

 

提示:如果在你的Linux环境下JnaCallback程序无法加载libJnaCbApi.so动态库,通常有两种解决办法。
1)将libJnaCbApi.so复制到系统的动态库目录,如 /lib 或 /usr/lib。
2)修改/etc/profile文件,在文件末尾添加命令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./,保存后注销或重启系统即可。添加这句命令的意思是让系统支持从“当前目录”加载动态库。


 

6.测试

 

【参考】:
分享到:
评论

相关推荐

    jni调用C++动态库,jna调用C++动态库

    4. **回调支持**:JNA支持Java方法作为本地函数的回调,这在处理事件驱动或异步操作时非常有用。 5. **内存管理**:JNA自动管理内存,无需手动处理`NewGlobalRef`等操作,但需要注意的是,如果本地函数返回Java对象...

    亲测可用,java 成功调用dll函数。包含调用回调函数,springboot版本。最近由于公司业务需要,要调用dll文件,用JNA调用。

    3. **回调函数**:在C/C++编程中,回调函数是指被其他函数调用的函数。在Java通过JNA调用DLL时,如果DLL函数需要一个回调函数作为参数,那么Java需要定义一个接口,该接口的方法将作为回调函数的实现,JNA会处理这个...

    JNA调用.dll文件或.so动态链接库的代码demo

    实现,JNA会自动加载对应的动态库并调用其中的方法。 3. **处理.dll和.so文件**: - **Windows (.dll)**:在Windows系统中,.dll文件是动态链接库,包含了可由多个程序共享的函数和数据。将.dll文件放在应用程序的...

    JNA实现回调及其他

    通过这个项目,开发者可以学习如何使用JNA进行跨语言调用,以及如何实现在Java中调用C/C++的回调函数。 ### 5. 应用场景 JNA广泛应用于各种场景,包括系统调用、硬件控制、图形界面、加密解密、性能优化等。由于其...

    JNA资源架包调用本地的动态库

    7. **回调和异步调用**:JNA也支持Java方法作为本地函数的回调,以及异步调用模式,这对于实现复杂的交互逻辑很有帮助。 8. **错误处理**:JNA通过异常处理机制报告本地调用的错误,如`LastErrorException`用于捕获...

    JAVA利用JNA调用DLL

    4. **Callback 机制**: JNA 还支持从本地库回调Java方法,这使得可以在本地库中调用Java实现的函数。 **JNA 调用DLL步骤** 1. **创建接口**: 创建一个Java接口,声明本地库中的函数签名。每个方法都应使用`native`...

    jna jar实现java调用dll

    JNA通过动态加载库和映射库函数来实现这一功能,极大地简化了Java与C/C++等本地代码之间的交互。在本文中,我们将深入探讨如何使用JNA jar包来实现Java调用dll文件。 首先,理解JNA的工作原理至关重要。JNA依赖于...

    jna-3.3.0 & jna-3.3.0-platform

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需编写C/C++的桥接代码。JNA通过映射Java方法到本地函数,实现了Java与操作系统底层功能的交互,极大地...

    jna 3.3.0 java 调用 dll/so

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码无需编写C/C++的JNI(Java Native Interface)代码,即可直接调用操作系统底层的动态链接库(DLL on Windows, SO on Linux/Unix)。JNA 3.3.0是...

    jna3.2.1.rar

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需编写C/C++的中间层,极大地简化了Java与本地操作系统接口的交互。JNA 3.2.1是该库的一个版本,提供了对...

    jna和examples的jar包

    4. **回调函数**:JNA 支持从本地代码回调 Java 方法,使得 Java 可以作为事件处理器或回调函数的实现。 5. **结构体和联合体**:JNA 支持 Java 中的类映射到本地结构体或联合体,可以包含嵌套结构、数组、指针等...

    JNA的jar包

    此外,JNA还支持回调(callbacks),使得C函数能够调用Java代码成为可能。 使用JNA的步骤通常包括以下几个部分: 1. 引入JNA库:首先需要将`jna.jar`添加到项目的类路径中,这可以通过IDE的配置或者构建工具(如...

    JNA所需要的jar包

    4. **回调函数**:JNA支持从本地库调用Java方法,只需要将Java方法作为参数传递给本地函数即可。 5. **内存管理**:JNA自动处理内存管理,包括分配和释放内存。但是,对于复杂的数据结构,用户可能需要手动管理内存...

    java调用dll需要的jna包

    Java调用DLL(动态链接库)是Java编程中的一项高级技术,主要依赖于Java Native Access (JNA) 库。JNA提供了一种无需编写本地代码(如C/C++)即可与本地平台API进行交互的方式,包括Windows上的DLL、Unix上的共享库...

    JNA需要的jar包

    描述中的“JNA的强大功能方便地调用动态链接库中的C函数”进一步强调了JNA的主要优点:它的易用性和灵活性,使得即使对C编程不熟悉的Java开发者也能轻松地利用本地库。 JNA的使用流程通常包括以下几个步骤: 1. **...

    jna.jar.zip

    它还支持回调函数,允许本地代码调用Java方法。此外,JNA还提供了一个动态类型系统,可以在运行时根据参数来确定函数调用的类型,这在处理不同平台或库的变体时非常有用。 在实际应用中,JNA常用于访问操作系统服务...

    JNA的API文档

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需编写C/C++的中间层,如JNI(Java Native Interface)。JNA通过提供一种抽象的方式来映射原生函数,使得...

    jna4.1.jar

    JNA还支持复杂的数据类型,包括结构体和联合,以及回调函数。通过自定义`Structure`子类,你可以定义Java类来表示本地结构体,并通过`ByReference`或`ByValue`类作为参数传递。 此外,JNA还包括一个Platform库,...

    JNA Jar包和使用教程.rar

    7. **回调函数**:JNA支持将Java方法作为参数传递给原生代码,这需要创建一个实现了特定接口的类,并使用`Callback`注解标记方法。 除了基础功能,JNA还包括了一些高级特性,如自动类型映射、内存管理、自定义类型...

    JNA Java Native Access

    4. **回调机制**:JNA支持将Java方法作为本地函数的回调,这样可以在本地代码中调用Java代码,增强了灵活性。 5. **平台兼容性**:JNA支持多种操作系统,包括Windows、Linux、macOS、Solaris等。它能够自动检测目标...

Global site tag (gtag.js) - Google Analytics