본문 바로가기

소프트웨어/Android/Java/Ndk

Android] NDK Project

이전글. NDK환경설정

http://mantdu.tistory.com/entry/Android-android-NDK



NDK를 적용한 간단한 프로젝트를 작성한다.


이클립스에서 안드로이드프로젝트를 생성하는 방법은 생략.


소스시작

package com.example.ndktest;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

	private TextView mText;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mText = (TextView)findViewById(R.id.text);
        
        NativeCall mNative = new NativeCall();
        int ret = mNative.add(10, 20);
        String retStr = mNative.stringFromJNI();
        
        mText.setText("retInt 0 : "+ret+", retString : "+retStr);
    }

}

소스끝


위와 같이 MainActivity를 꾸민다.

NativeCall은 아래와 같이 Native Method를 interface처럼 선언한다.


소스시작

package com.example.ndktest;

public class NativeCall {
	
	static {
		System.loadLibrary("my_lib");
	}
	
	public native int add(int i, int j);
	
	public native String stringFromJNI();
}

소스끝


System.loadLibrary()는 static으로 묶여서 Class가 생성되면서 불린다.

소스에서 native 지시자는 header파일 생성이 생성될 매서드를 지정한다.

선언은 NativeCall.java에서 하고 구현은 생성된 header에서 한다.



Makefile 만들기

프로젝트 폴더 아래에 jni 폴더를 만들고

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
# Here we give our module name and source file(s)
LOCAL_MODULE := my_lib
LOCAL_SRC_FILES := my_lib.c
 
include $(BUILD_SHARED_LIBRARY)


Android.mk파일을 만들어서 위의 내요을 채운다.


Header file 만들기

이제 c 소스를 작성해야 하는데 어떤 함수명으로 구현을 해야하는지 모른다.

그래서 jdk에서 제공하는 javah를 이용해서 자동으로 매서드의 이름을 생성한다.

우선 이에 앞서 진행되어야 하는것은


$vi /home/사용자이름//.bashrc 


로 bashrc를 연 후


export PATH=$PATH:/cygdrive/c/Progrm\ Files/Java/Jdk1.버전명/bin

을 지정해서 cygwin terminal이 javah를 쓸 수 있도록 해줘야한다.

또한 뒤에서 사용할 ndk-build를 위해 ndk path도 지정해줘야 한다.

export PATH=$PATH:/cygdrive/NDK를설치한 PATH/


:wq로 저장을 하고

source /home/사용자이름//.bashrc


로 변경 사항을 지정한다.




이제 Header를 만들어보자.

$ cd /cygdrive/c/Users/유저이름/workspace/프로젝트명

을 쳐서 프로젝트 폴더 최상위로 이동한다.

그 후

$ javah -classpath bin/classes com.example.ndktest.NativeCall

을 친다.

여기서 NativeCall은 java file로써 매서드가 선언되어있는 곳이다.

그 후 명령을 수행하면

위의 그림과 같이 . com_example_ndktest_NativeCall.h파일이 생성된다.




위와같이 사용해야하는 함수명이 자동 생성된것을 확인할 수 있다.

이 파일은 꼭 /jin/폴더 아래로 옮겨줘야 한다.


C코드 작성


jni폴더에 my_lib.c를 만들고 소스를 작성한다.



ndk-build

이제 작성된 소스를 갖고 .so파일을 만들어야 한다.

프로젝트 최상위 폴더로 이동 후

$ ndk-build를 하면 끝난다.

만약 빌드가 안된다면 .bashrc에 제대로 path를 지정하였는지 확인하길 바란다.



이렇게 나오면 성공한거다.


프로젝트에서 f5를 누르거나 project clean하면 lib/armeabi/xxx.so 파일이 생성된것을 볼 수 있다.


성공이다.

(추가적으로 armeabi가 뭐냐면.. arm architecture에 맞춰서 cross-comfile해주는 컴파일러 이름.

embedded 어쩌구인데..ㅋㅋ)