m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

Windowsで作成したDLLをJavaより呼び出して使用する

C言語で作成すると

超速いというのは知っていますが、そもそも他の言語で作成できるのかな?
と思ったので簡単なプログラムを作成して試してみる。

環境

f:id:m_shige1979:20161210152446p:plain

Windows64系のVC++でDLLを作成し、それをeclipseで実行する。

DLL作成

プロジェクトの作成でC++Win32のコンソールアプリケーションを選択

f:id:m_shige1979:20161210153121p:plain

ウィザードが立ち上がるのでそのまま次へを選択

f:id:m_shige1979:20161210153257p:plain

アプリケーションの種類を「DLL」を選択

f:id:m_shige1979:20161210153546p:plain

こうなります

f:id:m_shige1979:20161210153929p:plain

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
→ データ型が良くないので合わせる

所感

C++はわかりませんけどとりあえずは動かすことができました。
関数を実行することはできたけどクラス作ったやつのアクセスとかできるかもやってみたい。
同じような感じでいいのかな?