LoginSignup
4
2

More than 5 years have passed since last update.

JNAeratorを使用したJAVAと共有ライブラリの連携まとめ

Posted at

JNAeratorを使ってlinuxの共有ライブラリと構造体のデータ受け渡しをする方法の備忘録

Linuxの共有ライブラリとJAVAでデータのやり取りを行うときに構造体を使うのが思ったより簡単にできましたので、そのやり方をメモしておきます。

JNAeratorによる操作

JNAeratorをダウンロードします

ダウンロードはこちらから
https://code.google.com/archive/p/jnaerator/downloads

JNAeratorを実行する

xxxxxのところは、バージョン情報や日付などが入っていました。
java -jar jnaerator-xxxxxx-SNAPSHORT-xxxxx.jar

画面が起動したらヘッダファイルを貼り付けます

起動してコードを貼り付けた画面がこちら。(Raspberry Pi上で実行しています)

2016-08-14-142143_1366x768_scrot.png

JNAerate !ボタンを押す

JNAerate!ボタンを押した後の結果がこちら。右側の画面にJAVAのコードが生成されました。
2016-08-14-144118_1366x768_scrot.png

ファイルに保存する

右側の画面に表示されているコードをコピーしてファイルに保存します。ファイル名やクラスは「JNAerator class:」に表示されるのでそのまま使用しましょう。ただし、この時packageを使用したくなかったので、ファイル名はその部分を削除してSUBGHZ_MAC.javaにしました。

jarファイルのインストール

ここまでの作業で作成されたコードを使用するためには、ライブラリのインストールが必要です。
ライブラリのダウンロードはこちら
http://www.java2s.com/Code/Jar/j/Downloadjnaeratorruntime011jar.htm

ダウンロードしたライブラリはunzipして、javaのライブラリフォルダに保存します。
コピー先のフォルダは環境によって変わります。これはRaspberry Pi3の場合です。
$ unzip jnaerator-runtime-0.11.jar.zip
$ sudo cp jnaerator-runtime-0.11.jar /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/ext/

作成したライブラリの修正

作成した「SUBGHZ_MAC.java」を確認します。

一部直したほうが良いコードが有りましたので修正をしました。
+ ファイルの先頭行に含まれているpackageを消しました。
+ time_tのところがうまく変換出来ていないようです。linuxのtime_tは32bitのunsigned long型なので、NativeLongに変更しました。

実行するJAVAの作成

このようなコードを作成しました

//package com.lapis_semi.lazurite.io;
//import com.ochafik.lang.jnaerator.runtime.Structure;
import java.util.Arrays;
import java.util.List;
import java.util.Date;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.NativeLong;

public class LibraryTest {

    interface LazuriteLib extends Library {
        // load library
        LazuriteLib INSTANCE = (LazuriteLib) Native.loadLibrary("lazurite",LazuriteLib.class);

        // functions
        int lazurite_close();
        int lazurite_link(short addr);
        int lazurite_setRxAddr(short tmp_rxaddr);
        int lazurite_setPanid(short tmp_panid);
        int lazurite_setCh(byte ch);
        int lazurite_open();
        int lazurite_write(String payload, short size);
        int lazurite_available();
        int lazurite_read(char[] payload, short[] size);
        int lazurite_readRaw(SUBGHZ_MAC mac);
        int lazurite_getRxTime(Pointer tv_sec,Pointer tv_nsec);
        int lazurite_getRxRssi(Pointer rssi);
        int lazurite_getTxRssi(Pointer rssi);
        int lazurite_test(byte[] payload,short[] size);
    }
    public static void main(String[] args)
    {
        int result;
        LazuriteLib lazurite = LazuriteLib.INSTANCE;

        SUBGHZ_MAC mac = new SUBGHZ_MAC();

        byte ch = 36;
        short panid = (short)0xabcd;
        result = lazurite.lazurite_open();
        result = lazurite.lazurite_setCh(ch);
        result = lazurite.lazurite_setPanid(panid);
        System.out.println("result="+Integer.toString(result));
        do {
            result = lazurite.lazurite_readRaw(mac);
        } while(result <= 0);
        try {
            byte[] raw = mac.raw.getByteArray(0,mac.raw_len);
            String payload = mac.payload.getString(0);
            long t = (mac.tv_sec.longValue() & 0x0ffffffff)*1000 + (mac.tv_nsec.longValue() & 0x0ffffffff)/1000000;
            int rx_addr = mac.rx_addr[1] & 0x00ff;
            rx_addr = (rx_addr << 8) + (mac.rx_addr[0]&0x00ff);
            int tx_addr = mac.tx_addr[1] & 0x00ff;
            tx_addr = (tx_addr << 8) + (mac.tx_addr[0]&0x00ff);
            int rssi = mac.rssi & 0x0000ff;
            //rssi = rssi & 0x000000ff;

            System.out.print(new Date(t) + "\t" +
                    Integer.toHexString(rx_addr) + "\t" + 
                    Integer.toHexString(tx_addr) + "\t" + 
                    Integer.toString(rssi) + "\t" + 
                    payload);
        } catch (Exception e) {}
        result = lazurite.lazurite_close();
    }
}

共有ライブラリを使用するための宣言

importするライブラリの宣言と関数の宣言はこの部分になります。

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.NativeLong;

    interface LazuriteLib extends Library {
        // load library
        LazuriteLib INSTANCE = (LazuriteLib) Native.loadLibrary("lazurite",LazuriteLib.class);

        // functions
        int lazurite_close();
        int lazurite_link(short addr);
        int lazurite_setRxAddr(short tmp_rxaddr);
        int lazurite_setPanid(short tmp_panid);
        int lazurite_setCh(byte ch);
        int lazurite_open();
        int lazurite_write(String payload, short size);
        int lazurite_available();
        int lazurite_read(char[] payload, short[] size);
        int lazurite_readRaw(SUBGHZ_MAC mac);
        int lazurite_getRxTime(Pointer tv_sec,Pointer tv_nsec);
        int lazurite_getRxRssi(Pointer rssi);
        int lazurite_getTxRssi(Pointer rssi);
        int lazurite_test(byte[] payload,short[] size);
    }

構造体内部のメンバー変数の読み出し方

Pointer

仕様はこちら(https://jna.java.net/javadoc/com/sun/jna/Pointer.html)
文字列の取得:  String payload = = mac.payload.getString(0);
0のところは抽出するデータのオフセット
ByteArrayの取得: byte[] raw = mac.raw.getByteArray(0,mac.raw_len);
Pointer.getByteArray(offset,size);

NativeLong

long t = mac.tv_sec.longValue()

注意事項

次のようにC言事は異なる点が多々あるので、共有ライブラリからデータを取得した後にJAVAのデータ型に直したほうが良いです。
+ Javaにはunsigned型が無い
+ データ型のビット長がJAVAとC言語は異なる

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2