티스토리 뷰
JNI를 이용하여 C/C++에서 Java 함수를 호출 할 수 있다.
이때는 리플렉션을 이용한다. 개인적으로 Java를 처음 봤을 때 리플렉션 이런거 왜 존재하는 거야..하고 생각했었는데, 요즘 느끼는건 정말.. '강력하다'는 것이다. 웬만하면 변수명/함수명 등의 코드 이름으로 Java 내의 모든 기능을 다 이용 할 수 있으니.. 설계 관점에서 용이해진다. 물론 디버깅이나 가독성은 좀 떨어지는 감이 있지만..
C/C++에서 자바의 메소드를 호출하는 순서는 아래와 같다.
- FindClass 함수를 이용해서 Java의 클래스를 지정한다.
- 메소드명과 인자(시그니쳐)를 지정해서 클래스 내의 해당 메소드ID를 찾는다.
- 1,2에서 구한 클래스와 메소드를 이용하여 호출한다. 이때 반환값이나 정적/일반 메소드에 따라 메소드를 호출하는 방법이 다르다.
아래는 자바의 Integer클래스에 있는 parseInt 메소드를 호출해서 문자열을 int 타입의 숫자로 변환하는 네이티브 코드이다.
//인자로 jsting strInt를 받은 상태 jclass jklass = (*env)->FindClass(env, "java/lang/Integer"); //java.lang.Integer 클래스 jmethodId jmethod = (*env)->GetStaticMethodID(env, jklass, "parseInt", "(Ljava/lang/String;)I"); //static 메소드의 경우 위의 함수를 이용한다. 메소드명 "parseInt", 인자(시그니쳐) "(Ljava/lang/String;)I" //일반 메소드의 경우 GetMethodID 함수를 이용한다. if (jmethod == NULL) return; jint val = (*env)->CallStaticIntMethod(env, jklass, jmethod, strInt); //static 메소드를 call 하는 함수. 마지막의 strInt가 마치 자바에서 Integer.parseInt(strInt); 할때의 인자이다.
시그니쳐에 대한 자세한 설명은 JNI의 변수 타입과 시그니쳐(http://jhb.kr/315)를 참조하길 바란다.
위에서 찾은 메소드를 실행하기 위해서는 1. 반환값에 따라, 2.정적/일반 메소드 여부에 따라 호출하는 함수가 달라진다.
반환값 |
일반 메소드 |
정적(static) 메소드 |
Object |
CallObjectMethod |
CallStaticObjectMethod |
boolean |
CallBooleanMethod |
CallBooleanMethod |
byte |
CallByteMethod |
CallByteMethod |
char |
CallCharMethod |
CallCharMethod |
int |
CallIntMethod |
CallIntMethod |
long |
CallLongMethod |
CallLongMethod |
float |
CallFloatMethod |
CallFloatMethod |
double |
CallDoubleMethod |
CallDoubleMethod |
void |
CallVoidMethod |
CallVoidMethod |
일반 메소드는 Call[반환Type]Method, 정적 메소드는 Call[반환Type]StaticMethod를 사용한다.
멤버 변수 역시 리플렉션을 통해 가져와서 사용 할 수 있다.
mCount라는 int 타입의 멤버 변수를 가져오는 코드는 아래와 같다.
jfieldID jfield = (*env)->GetFieldID(env, jklass, "mCount", "I"); if (jfield == NULL) return; jint val = (*env)->GetIntField(env, jklass, jfield);
메소드 호출때와 비슷하게 Get[Type]Field 함수를 사용한다.
'Development > Mobile' 카테고리의 다른 글
[Android] Service 실행 여부 파악하기 (0) | 2015.11.29 |
---|---|
[Android] Android System Application (기본 설치앱) 지우기 (0) | 2015.11.29 |
[Android JNI/NDK] 로그 출력 (0) | 2015.09.21 |
[Android JNI/NDK] 배열 사용하기 (3) | 2015.09.21 |
[Android JNI/NDK] JNI를 이용해 Java에서 C 함수 호출하기 (0) | 2015.09.21 |
[Android JNI/NDK] JNI에서 C와 C++의 차이 (0) | 2015.09.18 |
[Android JNI/NDK] JNI의 변수 타입과 시그니처 (1) | 2015.09.18 |
[Android JNI/NDK] JNI와 NDK에 대한 대략적인 설명 (0) | 2015.09.17 |
- Total
- Today
- Yesterday
- 리눅스
- Visual C++
- source
- 안드로이드
- Quiz
- linux
- AWS
- algorithm
- winapi
- 프로그래밍
- java
- jni
- 드라이버
- jni강좌
- MFC
- NDK
- Cloud
- it
- driver
- db
- 음악
- database
- kering
- API
- C
- gcc
- android
- Troubleshooting
- Python
- C++
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |