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