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

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

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

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  2. Java基础之处理事件——实现低级事件监听器(Sketcher 2 implementing a low-level listener)

    控制台程序. 定义事件监听器的类必须实现监听器接口.所有的事件监听器接口都扩展了java.util.EventListener接口.这个接口没有声明任何方法,仅仅用于表示监听器对象.使用EventLi ...

  3. java中的接口回调

    [接口回调]接口回调是多态的另一种体现.接口回调是指:可以把使用某一个接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口中的方法.当接口变量调用被类实现的接口中 ...

  4. Java中jna的用法

    (1)jna是对jni的封装,让java使用者能更好的使用本地的动态库 (2)使用jna需要下载jna的jar包,该jar包就是对jni的封装,所以在调用效率上来讲,jna是要比jni低一点的,不过对 ...

  5. java 中的异步回调

    异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作 ...

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

    Java实现对组件事件(如单击.输入等)的监听和JavaScript类似,都是先添加Listener,再写触发函数,不同的是,Java实现监听前必须使用implements将各个接口添加到类内. 相关 ...

  7. 在Java中如何编写回调函数,以及回调函数的简单应用

    import static java.lang.System.out; import static java.lang.System.err; import java.util.logging.Lev ...

  8. 在XAML代码中为节点树安装事件监听器

    通过以下的演示样例代码,能够发现,我们能为随意的节点指定要监听的路由事件,而这个路由事件本身和这个元素可能根本就没有关系. <Window x:Class="Demo002.MainW ...

  9. Java事件监听器的四种实现方式

    自身类作为事件监听器 外部类作为事件监听器 匿名内部类作为事件监听器 内部类作为事件监听器 自身类作为事件监听器: import javax.swing.*; import java.awt.*; i ...

随机推荐

  1. 第8.14节 Python类中内置方法__str__详解

    一. object类内置方法__str__和函数str 类的内置方法__str__和内置函数str实际上实现的是同一功能,实际上str调用的就是__str__方法,只是调用方式不同,二者的调用语法如下 ...

  2. 从零开始的xxe学习

    本文介绍了一个菜鸡对xxe的一步步学习(内容多来源于大佬的博客,先感谢一波) 涉及知识点: (1)xxe 目录: 解析: 1.xxe是什么(不详解了,网上很多的) XXE(XML External E ...

  3. python+request+unittest+HTMLTestRunner

    https://www.imooc.com/article/details/id/20813 https://www.cnblogs.com/fennudexiaoniao/p/7771931.htm ...

  4. leetcode计划

    5.17 星期日,应完成的下周leetcode题目:279,300,1143,72,(前4个动态规划),104,110,543(后三个关于树)(https://cyc2018.github.io/CS ...

  5. IAR环境定义位变量标志位 STM8 MSP430通用

    首先建立一个公共点H文件,加入通用代码如下 typedef union { struct { unsigned char b0:1; unsigned char b1:1; unsigned char ...

  6. vue之keep-alive组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. STL——容器(deque) 构造 & 头尾添加删除元素

    1.deque容器概念 deque是"double-ended queue"的缩写,和vector一样都是STL的容器,唯一不同的是:deque是双端数组,而vector是单端的. ...

  8. ORACLE启用非默认监听端口

    1.修改listener.ora文件 LISTENER_TEST =         (DESCRIPTION =                 (ADDRESS = (PROTOCOL = TCP ...

  9. 系统类 字符串String类

    java编程语言中的字符串. 在java中,String类是不可变的,对String类的任何改变,都是返回一个新的String类对象. String 对象是 System.Char 对象的有序集合,用 ...

  10. ASP.NET Core 中间件的使用(二):依赖注入的使用

    写在前面 上一篇大家已经粗略接触了解到.NET Core中间件的使用:ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件, .NET Core框架中很多核心对象都是通过依 ...