테스트 프로그램 작성중 알게된 Java에서 dll을 사용하는 방법인 JNI, JNA의 샘플 소스코드
구글 검색 결과 JNI, JNA는 요새 안드로이드 코딩에 많이 사용하는 기술인듯 하다.
JNI에 비해 JNA는 다소 생소한 기술인듯 하고 샘플 코드 또한 잘 찾아 볼수 없는듯 했다.
JAVA에서 기존에 C++로 작성된 dll을 로딩하는 것이 신기했다.
Java 컴파일, 실행에 대한 사항이나 이클립스 설정 사항은 제외하여 작성하도록 하겠다.

1. JNI (Java Native Interface)

native code가 들어가 있는 java 소스코드 작성
*.java 코드를 컴파일 하여 *.class파일을 생성
javah를 이용하여 dll prototype이 포함되있는 *.h파일 자동 생성


*.h을 include하는 *.cpp파일을 작성하여 *.dll 파일을 생성
Java 소스에서 dll을 로딩하여 결과 확인

▶ 소스코드
아래의 샘플코드는 모든 프로그램의 가장 기초가 되는 HelloWorld를 메시지 박스로 출력하는 프로그램이다.
public class HelloWorld
{
 // TODO Auto-generated method stub
 native void Hello();
 static {System.loadLibrary("Hello_DLL");}
 
 public static void main(String[] args)
 {
  // TODO Auto-generated method stub
  HelloWorld myJNI = new HelloWorld();
  myJNI.Hello();
 }
}

▶ javah로 생성된 *.h 파일 (자동생성)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    Hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_Hello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

*.cpp 파일 - JNICALL Java_HelloWorld_Hello() 정의
// Hello_DLL.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include <tchar.h>
#include "HelloWorld.h"
#include "Hello_DLLDef.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;
}

JNIEXPORT void JNICALL Java_HelloWorld_Hello(JNIEnv *, jobject)
{
 Hello();
}

AOSSDK_API void Hello()
{
 MessageBox(NULL, _T("Hello World"), _T("test"), MB_OK);
}

▶ 결과



2. JNA (Java Native Access)

jna.jar

첨부되어 있는 jna.jar를 import 함
JNI와 비교하여 만들어져 있는 DLL을 수정 하지 않거나, 최소한의 수정으로 로딩하여 사용할수 있음
(JAVA에 맞는 Prototype을 수정해야 하는 문제가 있음 -> doc을 참조)
jna.jar의 package를 이용해 다양한 dll을 로드하여 사용할 수 있음

참고사이트 :
https://jna.dev.java.net/javadoc/overview-summary.html

▶ 소스코드
아래의 샘플코드는 C++로 작성된 mfcdll1.dll안에 있는 MyFunc()을 호출한다. MyFunc()은 int형의 두개의 인수를 받아 결과로 두 인수의 합을 반환하는 함수 이다.
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/**
 * JNA 샘플 코드 작성
 */
public class SampleJNAMain
{
 public interface SampleJNA extends Library
 {
  public int MyFunc(int a, int b);
 }
 
 // DLL 로딩
static {System.loadLibrary("mfcdll1");}
 
public static void main(String[] args)
 {
  // TODO Auto-generated method stub
  SampleJNA sample = (SampleJNA)Native.loadLibrary("mfcdll1", SampleJNA.class);
  System.out.println("Result = " + sample.MyFunc(2, 3));
 }
}

▶ 결과