반응형
[1]에서 보고 해보았다. 이전에 쓴 JNI와 같은 방식으로 컴파일하고 실행해보면 됀다.
1. Java Source
[Source 1] JniFuncMain.java
2. C++ Source
1. Java Source
public class JniFuncMain {
private static int staticIntField = 300;
static {System.loadLibrary("jnifunc");}
public static native JniTest createJniObject();
public static void main(String[] args) {
System.out.println("[Java] createJniObject() 네이티브 메소드 호출");
JniTest jniObj = createJniObject();
jniObj.callTest();
}
}
class JniTest
{
private int intField;
public JniTest(int num){
intField = num;
System.out.println("[Java] JniTest객체의 생성자 호출 : intField = " + intField);
}
public int callByNative(int num){
System.out.println("[Java] JniTest객체의 callByNative( " + num + "호출 ");
return num;
}
public void callTest(){
System.out.println("[Java] JniTest객체의 callTest() 메소드 호출 : intField = " + intField);
}
}
2. C++ Source
객체를 주고받을 때 알아야 할 것이 있는데 시그너처란 것이다.
아래 소스에서 "mid = env->GetMethodID(targetClass, "<init>", "(I)V");"의 "(I)V"와 같은 것이 시그너처이다.
이 시그너처는 JNI명세에 포함돼 있는 자바의 시그너처 생성 규칙을 토대로 개발자가 만들어도 되지만 오류를 방지하기 위해서 javap를 이용한다.
javap(자바 클래스 파일 디스어셈블러)
형식 : javap [option] 'classname'
option : -s 자바 시그너처 출력
-p 모든 클래스 및 멤버 출력
아래 소스에서 "mid = env->GetMethodID(targetClass, "<init>", "(I)V");"의 "(I)V"와 같은 것이 시그너처이다.
이 시그너처는 JNI명세에 포함돼 있는 자바의 시그너처 생성 규칙을 토대로 개발자가 만들어도 되지만 오류를 방지하기 위해서 javap를 이용한다.
javap(자바 클래스 파일 디스어셈블러)
형식 : javap [option] 'classname'
option : -s 자바 시그너처 출력
-p 모든 클래스 및 멤버 출력
[그림 1] javap를 이용한 시그너처 확인
#include "jniFuncMain.h"
JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject
(JNIEnv *env, jclass clazz)
{
jclass targetClass;
jmethodID mid;
jobject newObject;
jfieldID fid;
jint staticIntField;
jint result;
// JniFuncMain 클래스의 staticIntField 필드값 얻기
fid = env->GetStaticFieldID(clazz, "staticIntField", "I");
staticIntField = env->GetStaticIntField(clazz, fid);
printf("[CPP] JniFuncMain 클래스의 staticIntField 필드 값 가져오기\n");
printf(" JniFuncMain.staticIntField = %d \n", staticIntField);
// 객체 생성에 필요한 클래스 찾기
targetClass = env->FindClass("JniTest");
// 생성자 찾기
mid = env->GetMethodID(targetClass, "<init>", "(I)V");
// 객체 생성(객체 레퍼런스 반환)
printf("[CPP] JniTest 객체 생성 \n");
newObject = env->NewObject(targetClass, mid, 100);
// 객체의 메소드 호출
mid = env->GetMethodID(targetClass, "callByNative", "(I)I");
result = env->CallIntMethod(newObject, mid, 200);
// JniObject 객체의 intField 필드값 설정
fid = env->GetFieldID(targetClass, "intField", "I");
printf("[CPP] JniTest 객체의 intField 값을 200으로 세팅 \n");
env->SetIntField(newObject, fid, result);
// 생성한 객체를 반환
return newObject;
}
3. 실행결과
[그림 2] JniFuncMain 실행 결과
Reference
[1] 인사이드 안드로이드(Inside the Android Framework, 위키북스)
반응형
'Devlopment > Java' 카테고리의 다른 글
Aptana 플러그인 (0) | 2011.06.13 |
---|---|
싱글톤 패턴(Singleton Pattern) (0) | 2011.06.10 |
JavaHL (JNI) Not Available (0) | 2011.06.10 |
Builder Pattern (0) | 2011.06.09 |
달팽이 & 피보나치 수열 구현 (0) | 2011.06.01 |
두 개의 스택을 이용한 큐 구현 (0) | 2011.05.31 |
JNI(Java Native Interface) (0) | 2011.05.31 |
System.out.println의 재정의 (0) | 2011.05.13 |
[Linux, Window] JAVA로 로컬 IP 주소 얻어오는 방법 (0) | 2011.05.09 |
자바 enum에서 내부 String (0) | 2011.04.08 |