m_shige1979のときどきITブログ

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

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

https://github.com/mshige1979

JavaからDLLを呼び出してみる3

タイトルあんまり名前が繋がってない

まあ、意味は伝わるはず

やりたいこと

C++で作成したクラスをJavaで呼び出したい
でもできない(やりかたがわからない)ので関数でラップして使用する。

C++のクラス用DLLを作成

MathFuncsDll.h
// MathFuncsDll.h

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif

namespace MathFuncs
{
	// This class is exported from the MathFuncsDll.dll
	class MyMathFuncs
	{
	public:
		// Returns a + b
		static MATHFUNCSDLL_API double Add(double a, double b);

		// Returns a - b
		static MATHFUNCSDLL_API double Subtract(double a, double b);

		// Returns a * b
		static MATHFUNCSDLL_API double Multiply(double a, double b);

		// Returns a / b
		// Throws const std::invalid_argument& if b is 0
		static MATHFUNCSDLL_API double Divide(double a, double b);
	};
}
MathFuncsDll.cpp
// MathFuncsDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

namespace MathFuncs
{
	double MyMathFuncs::Add(double a, double b)
	{
		return a + b;
	}

	double MyMathFuncs::Subtract(double a, double b)
	{
		return a - b;
	}

	double MyMathFuncs::Multiply(double a, double b)
	{
		return a * b;
	}

	double MyMathFuncs::Divide(double a, double b)
	{
		if (b == 0)
		{
			throw invalid_argument("b cannot be zero!");
		}

		return a / b;
	}
}

ラッパー用

SampleDllWrapper.cpp
// SampleDllWrapper.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//

#include "stdafx.h"

#include "./MathFuncsDll.h"

double MyMathFuncs_Add(double a, double b) {
	return MathFuncs::MyMathFuncs::Add(a, b);
}
SampleDllWrapper.def
LIBRARY SampleDllWrapper
EXPORTS
  MyMathFuncs_Add @1

※DLLを参照して、ヘッダーファイルを指定する

Java

Sample02.java
package sample02;

import com.sun.jna.Library;
import com.sun.jna.Native;

interface HelloLib extends Library {
  HelloLib INSTANCE = (HelloLib) Native.loadLibrary("SampleDllWrapper.dll", HelloLib.class);

  // Cの関数名と一致させる
  double MyMathFuncs_Add(double s1, double s2);
}


public class Sample02 {

	public static void main(String[] args) {
		HelloLib hello = HelloLib.INSTANCE;

		double a = 100;
		double b = 1200;
	    System.out.println(hello.MyMathFuncs_Add(a, b));
	}

}

1300.0

※データ型がうまくあわないとエラーになりました(´・ω・`)

わかったこと

DLLを静的に読み込んでいるのでヘッダーファイルなどが必要。
最終的にはDLLだけでやりたいのでヘッダーファイルなしのバージョンも知りたい
難しいなあ(´・ω・`)