Windowsで作成したDLLをJavaより呼び出して使用する
C言語で作成すると
超速いというのは知っていますが、そもそも他の言語で作成できるのかな?
と思ったので簡単なプログラムを作成して試してみる。
DLL作成
ウィザードが立ち上がるのでそのまま次へを選択
アプリケーションの種類を「DLL」を選択
こうなります
SampleDll.cpp
// SampleDll.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。 // #include "stdafx.h" #include "stdio.h" int GetHello(int data) { printf("%d", data); return 0; }
※簡単な処理を作成する
SampleDll.def
LIBRARY SampleDll EXPORTS GetHello @1
※公開設定としてdefファイルを追加して以下を記載する
64bitでビルドし、エクスポート関数を確認する
>"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\dumpbin.exe" /exports SampleDll.dll Microsoft (R) COFF/PE Dumper Version 14.00.24215.1 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file SampleDll.dll File Type: DLL Section contains the following exports for SampleDll.dll 00000000 characteristics 584B9C0D time date stamp Sat Dec 10 15:09:17 2016 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 0001102D GetHello = @ILT+40(?GetHello@@YAHH@Z) Summary 1000 .00cfg 1000 .data 1000 .gfids 1000 .idata 3000 .pdata 3000 .rdata 1000 .reloc 1000 .rsrc 8000 .text 10000 .textbss >
Javaで実装
JNA用のパッケージが必要
GitHub - java-native-access/jna: Java Native Access
上のサイトよりjna.jarをダウンロードしてライブラリとして登録する。
Sample01.java
package sample01; import com.sun.jna.Library; import com.sun.jna.Native; interface HelloLib extends Library { // loadLibrary HelloLib INSTANCE = (HelloLib) Native.loadLibrary("C:/hogehoge/SampleDll.dll", HelloLib.class); // Cの関数名と一致させる int GetHello(int s); } public class Sample01 { public static void main(String[] args) { HelloLib hello = HelloLib.INSTANCE; hello.GetHello(100); } }
↓
100
詰みかけたところ
Windows64bitでJNAでJavaからC++コード呼び出そうとしてハマった話 - きしだのはてな
→ 32bitで作成したのを64bitで実行しようとしてエラーになった(´・ω・`)
java - Invalid memory access - Stack Overflow
→ データ型が良くないので合わせる
参考
http://blue-red.ddo.jp/~ao/wiki/wiki.cgi?page=JNI%A1%A2JNA%A4%CE%BB%C8%A4%A4%CA%FD
JavaからCの処理を呼ぶ方法(JNI/JNA/SWIG) - Qiita
GitHub - java-native-access/jna: Java Native Access
javaでwindowsのdllを利用する | Tech-Sketch
Visual Studio 2015でDLLを作成して動的読み込みしてみる。 - 小さい頃はエラ呼吸
所感
C++はわかりませんけどとりあえずは動かすことができました。
関数を実行することはできたけどクラス作ったやつのアクセスとかできるかもやってみたい。
同じような感じでいいのかな?