java中jna使用回调实现事件监听器——观察者模式

(1)C接口中的接口头文件

#pragma once
#include <iostream>
#include <vector>

#include <core/core.hpp>
#include <highgui/highgui.hpp>
#include <imgproc/imgproc.hpp>

#ifdef VIDEOPOSITION_EXPORTS
#define VIDEOPOSITION_API __declspec(dllexport)
#else
#define VIDEOPOSITION_API __declspec(dllimport)
#endif // VISION_EXPORTS

using namespace std;
using namespace cv;

typedef void(*Callback_ColorPos)(int color, float fX,float fY);
typedef void(*Callback_ImageOK)(int status);
extern "C"  int VIDEOPOSITION_API ColorPos(Callback_ColorPos GetColorPos,Callback_ImageOK GetImageSttus);
extern "C"  int VIDEOPOSITION_API OpenCamera(int index);
extern "C"  int VIDEOPOSITION_API CloseCamera();

我们可以看到,接口头文件中有三个函数,其中有一个函数的参数有两个回调类型。

(2)java中jna回调类的实现

package com.wxyz.scene_demonstration;

import com.sun.jna.Callback;

/**
 * 圆饼颜色和位置的回调接口
 *
 * @author dengchaoqun
 *
 */
public interface ColorPosListener extends Callback {//定义一个接口继承自jna的Callback类,对应上述头文件中Callback_ColorPos回调
    /**
     * 回调方法
     *
     * @param color
     *            圆饼的颜色
     * @param x
     *            圆饼的x轴坐标
     * @param y
     *            圆饼的y轴坐标
     */
    public void Status(int color, float x, float y);//对应C中回调接口中的三个参数,(对应上述头文件中Callback_ColorPos回调中的三个参数)
 }

(3)java回调接口的实现,实现ColorPosListener这个接口,实现Status方法,当动态库中有数据时, 数据就会传递到Status方法中的三个参数中,这样java端就可以监听动态库中的数据,并处理。

java对应动态库的接口如下

package com.wxyz.scene_demonstration;

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

/**
 * 动态规整接口
 *
 * @author dengchaoqun
 *
 */
public interface SceneDemo2API extends Library {
    SceneDemo2API INSTANCE = (SceneDemo2API) Native.loadLibrary("VideoPosition", SceneDemo2API.class);

    public int OpenCamera(int item);// 打开摄像头接口方法

    public int ColorPos(ColorPosListener GetColorPos, ImageOKListener GetImage);// 回调获取数据的方法

    public int CloseCamera();// 关闭摄像头的方法

}

java接口对应的实现类如下,以及使用demo如下

package com.wxyz.scene_demonstration;

@SuppressWarnings("unused")
public class SceneDemo2Control {
    private static boolean cameraStatus = true;// 相机打开的状态,默认关闭
    private static final float Y_point = 80.0f;// 图像识别原点在机械臂坐标系中y轴方向的坐标值
    private static final float Z_point = -312.5f;// 图像识别原点在机械臂坐标戏中z轴方向的坐标值,也就是吸圆饼的坐标值
    private static final float s = 339.5f;// 圆饼数据发送点距离机械臂原点的x轴方向的距离,用于计算时间来用。

    /**
     * 回调监听摄像头回传的圆饼数据,以及图片是否写好了的监听
     *
     * @param listener
     *            监听器,用户在使用的时候需要实现一个ColorPosListener接口,当有数据返回的时候就可以实时获取动态库回传的数据
     *            image
     *            监听器,用户在使用的时候需要实现一个ImageOKListener接口,20ms拍一张图片,当图片写好后,返回1,
     *            可更新界面imageView
     * @return 状态码 该方法是一个延时的方法,在摄像头打开后,会一直执行,在这个过程中只有当摄像头关闭后才会返回-1值
     */
    public static int getColorPos(ColorPosListener listener, ImageOKListener image) {
        if (cameraStatus == false) {
            System.out.println("摄像头没打开,请先成功的打开摄像头!");
            return -1;
        } else {
            int status = SceneDemo2API.INSTANCE.ColorPos(listener, image);
            return status;
        }
    }

    /**
     * 打开摄像头
     *
     * @param item
     *            表示是哪一个摄像头,从0开始
     * @return 打开摄像头的状态,-1表示打开失败,0表示打开成功
     */
    public static int openCamera(int item) {
        int status = SceneDemo2API.INSTANCE.OpenCamera(item);
        if (status == 0) {
            cameraStatus = true;
            System.out.println("摄像头打开成功!");
        } else {
            cameraStatus = true;
            System.out.println("摄像头打开失败!");
        }
        return status;
    }

    /**
     * 关闭摄像头的方法
     *
     * @return 状态吗,-1表示关闭失败,0表示关闭成功
     */
    public static int closeCamera() {
        int status = SceneDemo2API.INSTANCE.CloseCamera();
        if (status == 0) {
            cameraStatus = true;
            System.out.println("摄像头关闭成功!");
        } else {
            cameraStatus = true;
            System.out.println("摄像头关闭失败!");
        }
        return status;
    }

    // demo
    public static void main(String[] args) {
        openCamera(1);
        getColorPos(new ColorPosListener() {
            @Override
            public void Status(int color, float x, float y) {
                // color的对应关系,0红色,1绿色,2蓝色,3黄色,4白色,5紫色
                x = Math.round(x);// 吸球点的x坐标系是固定,需要根据实际的去定位吸球的
                y = Math.round(y) - Y_point;
                if (color == 1) {// 假定两种颜色分别是1,2
                    // 调用运动方法,气嘴吸饼,运动到指定的一边

                } else if (color == 2) {
                    // 调用运动方法,气嘴吸饼,运动到指定的一边

                }
                System.out.println(x + "::" + y);
            }
        }, new ImageOKListener() {

            @Override
            public void GetImage(int imgReady) {
                // TODO Auto-generated method stub
                if (imgReady == 1) {// 图片写好了
                    // 更新imageView的值
                } else if (imgReady == 0) {// 正在写图片

                }
            }
        });
        closeCamera();
    }
}

原文地址:https://www.cnblogs.com/deng-c-q/p/8310061.html

时间: 2024-10-12 23:01:13

java中jna使用回调实现事件监听器——观察者模式的相关文章

[原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

Java中的接口回调

接口回调是多态的另一种体现.接口回调是指:可以把使用某一个接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口中的方法.当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,成为接口回调.不同的类在使用同一接口时,可能具有不同的功能体现.即接口的方法体不必相同,因此接口回调可能产生不同的行为. 接口回调会方便功能的扩展,在主功能外由框架层实现定制功能处理. 现在有两个类,一个是A,一个是B,回调就是A去调用B中的某个方法,然后B又回调A中

Java中的设计模式(七):观察者模式

介绍 观察者模式是行为设计模式之一.当您对对象的状态感兴趣并希望在有任何更改时收到通知时,观察者设计模式非常有用.在观察者模式中,监视另一个对象状态的对象称为Observer,正在被监视的对象称为Subject. 根据GoF,观察者设计模式的意图是; 定义对象之间的一对多依赖关系,以便当一个对象更改状态时,将自动通知和更新其所有依赖项. Subject包含一个观察者列表,用于通知其状态的任何变化,因此它应该提供观察者可以注册和注销自己的方法.Subject还包含一种方法,用于通知所有观察者任何更

java 中的异步回调

异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作,然而真正干活的是CallBackBody,它里面的execute才是真正要处理的事情,如果成功,则触发onSucess,否则触发onFailure. CallBackApp做为最终的运行舞台,这里面还得单独跑一个线程,来启动CallBackTask,这样才不会阻塞后面的处理. CallBackBo

Java学习笔记(二)事件监听器

Java实现对组件事件(如单击.输入等)的监听和JavaScript类似,都是先添加Listener,再写触发函数,不同的是,Java实现监听前必须使用implements将各个接口添加到类内. 相关的库为java.awt.event.* 例如要添加行为事件的接口ActionListener,则需要在实现窗口的类内作如下操作: public class Test extends JFrame implements ActionListener{     public Test(){       

java设计模式--观察者模式和事件监听器模式

文章转载于:http://www.java2000.net/p9452 复习设计模式,看到observer观察者模式,说法是该模式和iterator迭代器模式类似已经被整合进jdk,但是jdk提供了两种接口: 一.java.util.Observer -- 观察者接口 对应: java.util.Observable --受查者根类 二.java.util.EventListener -- 事件监听/处理接口 对应: java.util.EventObject -- 事件(状态)对象根类 研究了

java中过滤器和监听器详解

先说一下java中过滤器的作用: 过滤器是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url.主要为了减轻服务器负载.减少压力 拦截器的作用: 拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法.比如可以用拦截器做一些权限管理 或者log之类的事情. 过滤器和拦截器他们的作用是不同的.   Java中过

Spring 4.2框架中注释驱动的事件监听器详解

事件交互已经成为很多应用程序不可或缺的一部分,spring框架提供了一个完整的基础设施来处理瞬时事件.下面我们来看看Spring 4.2框架中基于注释驱动的事件监听器. 1.早期的方式 在早期,组件要从Spring事件获知自定义域事件中获取通知,那么组件必须实现ApplicationListener接口并覆写onApplicationEvent方法. @Component class OldWayBlogModifiedEventListener implements ApplicationLi

[转]Java事件处理机制- 事件监听器的四种实现方式

原文来自http://stefan321.iteye.com/blog/345221 自身类作为事件监听器 外部类作为事件监听器 匿名内部类作为事件监听器 内部类作为事件监听器 自身类作为事件监听器: Java代码   import javax.swing.*; import java.awt.*; import java.awt.event.*; /** *Java事件处理机制:自身类作为事件监听器 *@author Winty([email protected]) *@version 200