Java Native Accessの実装例を見てみましょう。
まず実装するのは OpenCL ライブラリを使用した C 言語のソースコードです。
HelloJNA.c.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <OpenCL/cl.h> #include <assert.h> int square(int num) { return num*num; } int squareArray(int* num) { int i,sum = 0; for(i = 0; i<3; i++) { num[i] *= num[i]; sum += num[i]; } return sum; } const char* helloReply(const char* msg) { printf("%s\n",msg); msg = "I'm from C language!"; return msg; } const char* checkDevice() { cl_platform_id platform; cl_device_id *devices; cl_uint num_devices; cl_int i, err; char *name_data = malloc(sizeof(char)*48); err = clGetPlatformIDs(1, &platform, NULL); if(err < 0) { perror("failed to find platforms"); exit(1); } err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, NULL, &num_devices); if(err < 0) { perror("Failed to find devices"); exit(1); } devices = (cl_device_id*) malloc(sizeof(cl_device_id) * num_devices); clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL); for(i=0; i<num_devices; i++) { err = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(char)*48, name_data, NULL); if(err < 0) { perror("Failed to read device name"); exit(1); } printf("CL_DEVICE_NAME: %s\n",name_data); clReleaseDevice(devices[i]); } free(devices); return name_data; } void destroy(char* data) { assert(NULL != data); free(data); }
このソースコードは OpenCL ライブラリを使った C 言語でストレートに実装しています。
ヘッダーファイルを作らないといけない JNI に比べるとこれは大きな利点となります。
次に Java サイドの実装を見てみましょう。
JNAの実装の基本部分は「com.sun.jna.Library」を実装したインターフェースを作ることからはじめます。
インターフェース内に、C言語のソースで定義した関数に対応したメソッドを宣言します。
最後にインターフェースのインスタンスを生成して、メソッドを呼び出せば一連の実装は完了となります。
HelloJNA.java.
package com.book.jocl; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.PointerType; import com.sun.jna.ptr.ByteByReference; interface HelloLib extends Library { //(1) HelloLib Instance = (HelloLib) Native.loadLibrary("hello", HelloLib.class); //(2) ByteByReference checkDevice(); //(3) int square(int num); int squareArray(int[] array); ByteByReference helloReply(String msg); void destroy(Pointer ptr); } public class HelloJNA { public static void main(String[] args) { HelloLib hello = HelloLib.Instance; //(4) ByteByReference dev_info = hello.checkDevice(); //(5) Pointer dev_ptr = dev_info.getPointer(); //(6) String dev_str = dev_ptr.getString(0); //(7) System.out.println("checkDevice function returns: "+dev_str); hello.destroy(dev_ptr); //(8) int squared = hello.square(5); System.out.println(squared); int squaredArray[] = new int[10]; for(int i =0; i < 3; i++) { squaredArray[i] = i+1; } int returnedSquare = hello.squareArray(squaredArray); System.out.println(returnedSquare); ByteByReference reply = hello.helloReply("Hello World! JNA!"); Pointer ptr = reply.getPointer(); String str = ptr.getString(0); System.out.println(str); } }
Copyright 2018-2019, by Masaki Komatsu