-----------------------------------------------------------------------------------
출처: http://blog.naver.com/slaghter/5801897
-----------------------------------------------------------------------------------
▶ 문제
JNI를 사용하는 자바의 클래스가 패키지형태로 되었을 경우
즉, 코드가
package com.javapattern.jni;
import ...
publc class ...
라고 되어 있을 경우 백날 해봐야 위의 exception이 난다.
위와 같은 문제가 발생을 할 경우 JNI에 대한 컴파일 방식이 달라져야 한다
▶ package 형태의 java class에서 JNI의 사용
보통의 JNI는 아래와 같은 특수한 format의 메소드가 사용이 됩니다.
Class이름이 TestJNI 라고 가정 하면
public native void methodName();
인터페이스 선언과 비슷하게 생겼습니다..
위의 methodName에 해당하는 native function은 아래와 같은 형태의 header로 작성이 되게 됩니다.
JNIEXPORT void JNICALL Java_클래스이름_메소드이름(arg);
변환해보면 header파일은
JNIEXPORT void JNICALL Java_TestJNI_methodName(JNIEnv *, jobject);
이 됩니다.
위와 같은 헤더파일을 작성하기 위해서는 package형태의 JNI클래스를 compile 해야 합니다.
당근 원래의 클래스파일을 이미 컴파일된 상태여야 하고, 그런 후에 javah명령어를 써서 하게 됩니다.
즉,
javah com.javapattern.jni.JNITest
자 그러면 차례차례로 클래스를 작성하는 것부터 보도록 하면.....
아래와 같이 auth를 따는 클래스를 작성한다고 가정하면...
package com.javapattern.util; public class AuthUtil { /** Native import */ public static native String SetAuthenticationValC( String cmd, int version, int keyindex, String key1, String key2); public static native int GetAuthenticationValC( String cmd, int version, int keyindex, String key1, String key2, long auth); static { System.out.println("Load"); try{ System.loadLibrary("Callxfsp"); }catch(Exception e) { e.printStackTrace(); } System.out.println("Load OK!"); } public static String getAuth() { return SetAuthenticationValC("SO", 1, 6, "25", "45"); } } |
먼저 위의 클래스를 컴파일합니다. 소스의 위치는 compile root로부터 com/javapattern/util에 위치시킵니다.
그런 후에
javac ./com/javapattern/util/AuthUtil.java
명령이 성공하게 되면 com/javapattern/util의 디렉토리에 AuthUtil.class가 생기게 됩니다.
그러면 현재 compile시킨 root디렉토리에서 다시 javah를 이용하여 해당 header파일을 작성하도록 합니다.
javah com.javapattern.util.AuthUtil
위의 명령이 다시 성공하게 되면 header파일의 이름은 com_javapattern_util_AuthUtil.h파일로 생성됩니다.
그런 다음 C소스의 header에 위의 compile된 .h파일을 include시키도록 한 후 C를 작성하도록 합니다.
#include <stdio.h>
#include <memory.h>
#include "tubis_asi_wli_util_XFSPUtil.h"
#include "authutil.h"
/*
* Class: Call.java
* Method: SetAuthenticationValC
* Signature: ()I
*/
JNIEXPORT jstring JNICALL Java_com_javapatteru_util_AuthUtil_SetAuthenticationValC
(JNIEnv *env, jclass clazz, jstring jcmd, jint jversion, jint jkeyindex, jstring jkey1, jstring jkey2)
{
int iret = 0;
char cret[10+1];
char cmd[4096];
char key1[4096];
char key2[4096];
unsigned long auth=0;
// 이하 소스 주절주절
}
|
그런 다음에 C source를 컴파일하여 윈도우라면 dll, Unix라면 so파일을 컴파일하여 만들도록 합니다.
그리고 해당 dll이면 path에 so파일이면 LD_LIBRARY_PATH에 라이브러리 파일을 참조하도록 한 후
자바클래스로 호출하면 됩니다.
import com.javapattern.util.AuthUtil;
public class Call {
public static void main(String [] args) {
String str = AuthUtil.getAuth();
System.out.println(str);
}
}
|
'IT_Programming > Java' 카테고리의 다른 글
[Java] ClassLoader에 대해서.. (0) | 2010.11.18 |
---|---|
[펌] Java AWT:Lightweight UI Framework (0) | 2010.10.08 |
사용자 정의 마우스 커서 만들기 (0) | 2010.09.27 |
[펌] 이미지 크기 변환할 때 품질 유지하기 (0) | 2010.09.06 |
[펌] Java Concurrency: Executor와 Callable/Future (0) | 2010.09.06 |