인터넷의 수 많은 ndk 설치 글들을 보면 거의 대부분의 글들이 cygwin을 설치하고 cygwin의 쉘 상에서 ndk-build


명령을 수행하는 식으로 설명을 하고 있다. 나는 cygwin을 왜 사용해야하는지 정확히 몰랐는데 왜냐하면 굳이 cygwin


을 설치하지 않고 윈도우즈의 cmd를 사용해도 ndk-build가 잘 되었기 때문이다.


cygwin이 정확히 왜 필요한지를 찾는 도중..


http://stackoverflow.com/questions/10481132/cygwin-for-android-ndk-programming


이와 같은 자료를 찾게 되었다.


요약 : ndk7버전부터는 cygwin의 설치 없이도 ndk를 이용할 수 있으나 ndk-gdb script는 사용할 수 없다. 즉, 디버


깅을 하려면 cygwin이 필요하다(혹은 다른 무언가)


이 얘기는 ndk7버전을 소개하는 글에 나와있던 얘기이므로 현재 10버전까지 올라오면서 기능이 개선되었을 수도 있


겠으나 찾아보지 않았다.


참고 글 : http://developer.android.com/tools/sdk/ndk/index.html


---------------------------------------------


1.


http://developer.android.com/tools/sdk/ndk/index.html


위의 사이트에서 자신의 환경에 맞는 ndk 버전을 선택해 다운 받는다. (나의 경우 windows 32bit ndk 10버전)


압축을 적당한 곳에 풀고(나의 경우 C:\), ndk-build를 사용하기 편하게 환경변수 Path에 등록한다.


C:\android-ndk-r10b;


cmd창을 열고 설정이 잘 되었는지 ndk-build를 입력해본다.




(이 글의 결론적인 목표는 ndk-build를 사용해서 c코드를 so파일로 빌드하는 것이다)


2.


테스트를 할 안드로이드 프로젝트를 만든다. (나의 경우 NDKTest)





3.


Eclipse에서 Window -> Preferences -> Android -> NDK에서 NDK Location을 자신이 android ndk를 설치한 경로


로 설정해주자.





4.


프로젝트 우클릭 -> Android Tools -> Add Native Support 에서 library name을 적당히 적어주자.





이렇게 하고나면 프로젝트에 jni 폴더가 생기고, 그 안에 cpp파일과 mk파일이 생겼음을 알 수 있다.




여기서 cpp파일에는 내가 so파일로 빌드하기 위한 함수들을 작성해주면 되고, mk파일에는 ndk-build를 이용해 so


파일을 빌드할 때의 일련의 규칙들을 적어준다. Add Native Support를 사용하지 않더라도, 프로젝트에는 jni폴더가 


있어야 하고, 그 안에 c(혹은 cpp)파일들과 mk파일들이 위치해야 한다. Add Native Support는 단지 이러한 일련의 


과정을 이클립스 측에서 편하게 수행해줄 뿐이다.


* 사용하는 목적에 따라 cpp파일을 c파일로 고쳐 쓴다거나 각자의 목적에 맞게 바꿔 쓰자.


5.


jni를 사용 하기 위해서 native 선언문 및 so파일 호출문을 포함하는 자바소스파일을 생성한다. (나의 경우 JNITest)


그리고 다음과 같이 작성 한다.





package com.example.ndktest;


public class JNITest {


static {

System.loadLibrary("NDKTest");

}


public native String stringFromJNI();

}


6.


이제 이 소스파일을 토대로 c 헤더파일을 작성해야 한다. 이 때 javah를 사용한다.


먼저 5번에서 만든 소스파일의 클래스파일이 어디에 위치해있는가를 확인한다.


(나의 경우 C:\AndExam\NDKTest\bin\classes\com\example\ndktest)


그리고 cmd를 열고 C:\AndExam\NDKTest\bin\classes\com\example\ndktest 까지 이동한 다음 javah 명


령을 내려서 위의 소스파일을 토대로 c 헤더파일을 만들어낸다





JNITest 클래스 파일을 찾을 수 없다고 한다. 사실 이 문제는 예전에 자바로 JNI를 이용할 때 이미 겪어본 문제이며 


해결책도 이미 알고 있다. (참고 : http://huammmm1.tistory.com/443)


요령은 javah의 classpath를 패키지명 바로 앞까지 설정하고, 소스파일을 지정할 때 패키지명.패키지명.소스파일 이


런식으로 주면 되는 것이었다.





나의 경우 패키지명이 com.example.ndktest 이므로 바로 앞인 classes 폴더까지를 classpath의 옵션으로 주고, 뒤에


소스파일은 com.example.ndktest.JNITest로 주었다.


이제 만들어진 c헤더파일을 프로젝트\jni\ 안에 넣어준다.





7.


앞에서 만든 헤더파일을 열어보니 심상치 않은 에러들이 발생한다.





이클립스에서 JNI 관련 구문들 (JNICALL, JNIEnv, jobject, ...)을 인식하지 못하고 있다.


이를 해결하기 위해서 프로젝트 우클릭 -> Properties -> C/C++ General -> Paths and Symbols에 들어간다음,


Includes란에서 Add... 버튼을 누르고 File System... 버튼을 눌러 다음과 같은 경로를 추가해주자.


C:\android-ndk-r10b\platforms\android-16\arch-arm\usr\include


* ndk 버전 및 안드로이드 버전은 본인의 환경과 맞게 설정한다.





OK버튼을 누르고 Apply한다.





에러들이 사라졌다.


8.


이제 헤더파일에 기술한 함수 선언문을 긁어서 jni폴더의 cpp파일 안에 넣어주고 함수의 뼈대를 만든다.







#include <jni.h>

#include "com_example_ndktest_JNITest.h"


JNIEXPORT jstring JNICALL Java_com_example_ndktest_JNITest_stringFromJNI

  (JNIEnv * env, jobject jobj) {

return (env)->NewStringUTF("Hello NDK!");

}


* 헤더파일을 #include로 추가해주었고,


* 헤더파일의 선언문에는 인자에 이름이 생략되어 있어서 cpp파일에 넣는 과정에서 env, jobj로 이름을 주었다.


9.


이제 메인액티비티로 돌아가서, 5번에서 만든 자바 클래스를 생성하고 stringFromJNI 메서드를 호출해서 JNI가 제대


로 동작하는지를 확인해본다.





package com.example.ndktest;


import android.os.*;

import android.support.v7.app.*;


public class MainActivity extends ActionBarActivity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

JNITest jniTest = new JNITest();

System.out.println(jniTest.stringFromJNI());

}

}


10.

이제 마지막 일은 ndk-build 명령을 통해 내가 jni폴더에 만들어둔 cpp파일 및 헤더파일을 토대로 so파일을 만드는

것이다. 

4번에서 Add Native Support를 이용했다면 프로젝트 우클릭 -> Build Configurations -> Build All을 누르면 알아서

ndk-build 명령이 실행되어 다음과 같이 빌드가 될 것이다.


* 맨 앞의 WARNING은 단순한 경고이므로 신경쓰지 않았다


만약에 이 방법으로 빌드가 되지 않는다면 직접 cmd에서 ndk-build 명령을 수행하는 방법이 있다.

다음과 같이 cmd를 실행해서 프로젝트의 루트폴더까지 이동한다음 ndk-build 명령어를 내려 본다.



ndk-build 명령이 정상적으로 수행되었다면 프로젝트폴더\libs\armeabi에 so파일이 생성되었을 것이다.



이제 안드로이드 프로젝트를 실행하면,





다음과 같이 Hello NDK!가 출력되는 것을 알 수 있다.





Posted by huammmm1
,