|
갑자기 뜬금 없이 JNI라니.. 안드로이드에도 C 기반의 엔진을 지원하다보니 JNI파일을 함께 빌드해야하는 경우가 종종 생긴다. 근데, 처음 접해보면 JNI라는게 참... 불편하다. 특히나, C 기반의 엔진 API가 구조체와 같은 매개변수를 주고 받는다면, 더욱 그렇다. 예를 들어보자. C 기반 라이브러리의 API 파일 clib.h에 다음과 같이 정의되어 있다. // ----------------------------------------------------------------------- // clib.h typedef struct tagTestStruct { int nA; int nB; int nC; } TestStruct; SetParam(TestStruct * pParam); // ----------------------------------------------------------------------- 그리고, 이 라이브러리를 사용하기 위해 wrapper 역할을 하는 API.java파일과 struct를 대체를 testobj.java가 다음과 같이 정의되어 있다. // ----------------------------------------------------------------------- // api.java public class API{ static { System.loadLibrary("clib"); } private API() {} public final static native int SetParam(final int type, Object obj); // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // testobj.java public class TestObj{ public TestObj() {}; public int nA= 0; public int nB = 0; public int nC = 0; } // ----------------------------------------------------------------------- 그리고, javah -jni 명령어를 사용하여 다음과 같이 jni파일을 생성한다. // ----------------------------------------------------------------------- // testobj.java JNIEXPORT jint JNICALL Java_com_SetParam (JNIEnv *env, jclass obj, jint paramtype, jobject param) { } // ----------------------------------------------------------------------- 문제는 세 번째 매개변수인 jobject type으로 전달된 class TestObj의 멤버 변수 값들을 가져오는 방법이다. 먼저, 다음과 같이 jobject타입의 매개변수 param의 class를 구한다. jclass cls; cls = (*env)->GetObjectClass(param); 그리고 class의 각 멤버 변수의 id를 구한다. jfieldID fid;fid = (*env)->GetFieldID(env, cls, "nA", "I"); 이제, class와 field id 정보를 알게 되었기 때문에, field값을 가져오면 된다. jint nA = (*env)->GetIntField(env, param, fid); http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/functions.html#wp23720
매크로로 정의된 두 개의 string을 연결하려고 strcat을 구현해서 쓰고 있는데, 팀원이 한 가지 팁을 알려줬다.
##을 이용해서 매크로로 동일한 기능을 구현할 수 있다는 것이다. 예를 들어, #define TEXT1 "macro " #define TEXT2 "test" 이렇게 정의된 두 개의 매크로 TEXT1과 TEXT2를 합쳐보자. #define STRCAT(x, y) x##y 이렇게 정의해놓고, 다음과 같이 호출해보자. STRCAT(TEXT1, TEXT2); 그러면 이런 결과가 나온다. TEXT1TEXT2 움~ 그럼 어떻게 해야 정의된 값들로 연결이 될까? 매크로를 중첩해서 사용하면 됩니다. #define MAKE(x, y) x##y #define STRCAT(x, y) MAKE(x, y) 이렇게 정의해서 동일하게 호출하면, 다음과 같이 원하던 결과를 얻을 수 있다. macro test
C 교재에서 extern 변수의 사용에 대한 설명을 보면, 다음과 같이 사용하는 예를 많이 든다.
----------------------------------------- // test1.c int test; ----------------------------------------- ----------------------------------------- // test2.c extern int test; ----------------------------------------- 간단한 프로그램의 경우 이러한 방식으로 extern을 사용하면 다른 파일에 있는 전역 변수를 끌어다 쓰기가 편하다. 하지만, 파일수가 상당히 많은 솔루션의 경우 위와 같은 방법으로 extern을 사용하게 되면 여러 소스 파일에서 extern을 남발하여 사용하게 된다. 컴파일러 입장에서는 전혀 문제될 것이 없지만, 프로그래머 입장에서 보면, 변수가 전혀 관리가 되지 않는 형태로 가게 된다. 이럴 때는 헤더파일에 변수의 선언부를 두고, 하나의 소스 파일에만 정의를 해두는 것이 전체적인 관리 측면에서 용이하다. ----------------------------------------- // test1.h extern int test; ----------------------------------------- extern으로 정의가 아닌 선을을 했기 때문에 소스 파일에 정의를 해주어야 한다. ----------------------------------------- // test1.c #include "test1.h" int test = 0; ----------------------------------------- ----------------------------------------- // test2.c #include "test1.h" func() { test = 1; } -----------------------------------------
요즘 들어 프로그래머로서, 벤처나 중소기업에 지원할 경우 기술면접을 보게 되는 경우가 종종 있다.
C언어 경험자라고 하면, 언제나 포인터에 대해 얼마나 잘 이해하고 있는가를 테스트 하기 위해 아래와 같은 문제와 유사한 형태를 제시하는 경우가 허다하다. 매개변수로 char* 형태의 string을 받아서 string내부의 space를 제거하여 돌려주는 코드를 작성하라. 단, 함수 내부에서 메모리 연산과 관련된 stand library는 사용할 수 없다. 자, 그럼 일단 내부에서 char*를 동적할당하여 space를 제외한 나머지를 복사하는 방법은 취할 수 없다. 따라서 가장 먼저 떠오르는 방법은 space 이후 값들을 앞으로 하나씩 당기는 방법이다. ![]() ![]() ![]() ![]()
|
by 황씨 카테고리
최근 등록된 덧글
이거원... Scatter Loa..
by 이터널블루 at 07/20 나도 예전에 노말폰 플랫.. by 황씨 at 10/28 원래 이렇게 하는건데 .. by 황씨 at 10/28 원래 이렇게 하는 것 아.. by 노헝그리 at 10/27 난 가급적이면 매크로를.. by 노헝그리 at 10/27 이건 폰 쪽이라기보단.... by 황씨 at 09/23 니 블로그를 볼 때 마다 .. by 노헝그리 at 09/18 -ㄴ- 그냥 게시판이 필.. by 황씨 at 08/28 레알 유러피언 스타일의.. by 노헝그리 at 08/28 헉.. 여기를 다 방문해.. by 황씨 at 08/28 최근 등록된 트랙백
이전 블로그
이글루 링크
태그
API
gcc
overridding
가상함수
동적할당
allocation
__user_initial_stackheap
macro
virtualfunction
unittest
JNI
passbypointer
maloc
RTM
concatenation
RO
handwriting
jobject
다형성
RW
extern
robustprogramming
make
scatterloading
포인터
오버라이딩
archive
recognition
polymorphism
전역변수
| |||