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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM