xcode 에서 java JNI 사용하기




xcode  에서 JNI 를 사용하려면 어떻게 해야 하는지 알아 보도록 하겠습니다.

처음 xcode 를 접하면, 어떤 기능들이 있고 메뉴 구성이 어떻게 되어 있는지 몰라서 적응이 잘 안됩니다. :)

그러나 조금 사용하다보면, 정말 편하다는 생각을 하게 됩니다.


각설하고 먼저  아래와 같이 Java 코드를 작성합니다.



public class TestMain {
    static {
        System.loadLibrary("JNI4Mac");
    }
    public static native String getMessage();

    public static void main(String[] args) {
        System.out.println(TestMain.getMessage());
    }
}



JNI4Mac 이라는 JNI 파일에는 getMessage() 가 선언되어 있어야 합니다.

그리고 이를 호출하는게 전부입니다.


그럼 이제 본격적으로 JNI 파일을 만들어 보도록 하겠습니다.





[xcode 를 실행하면, 위와 같이 환영 메세지와 함께 최근 프로젝트 목록이 뜹니다.]



[Mac OS X 에서 개발하는 것이므로, Mac OS X 의 Framework & Library  에서  C/C++ Library 를 선택합니다.]

사실 Cocoa Library 를 선택해도 무관합니다. :)



[Type 을 반드시 Dynamic 으로 선택해야 합니다. ARC(Automatic Reference Counting) 은 취향에 맞게 선택합니다. 저는 개인적으로 ARC 를 사용하였습니다.]

ARC 에 대해서 잘 모르시는 분들은 자료를 찾아 보시기 바랍니다. (메모리 관리 방식입니다.)



[프로젝트를 생성할 위치를 선택합니다.]


[좌측 프로젝트 View 에서 프로젝트를 클릭하면 위 화면과 같이 빌드설정 창이 뜹니다.]




[Target 설정을 보면, Architectures 가 보입니다.]


[xcode 의 설정 메뉴]


xcode 를 처음 썼을 때, Visual Studio 와는 조금 달라 적응이 안되었습니다.

일단 Build 를 하게 되면, 결과물이 프로젝트 폴더 안에 생성되는게 아니라,

xcode 에서 설정된 폴더에 생성이 됩니다.


즉, A, B, C 프로젝트 모두 빌드를 하고나면, A, B, C 프로젝트 폴더 하위에 생기는게 아니라,

공통된 이상한 폴더에 생성됩니다.


이 부분을 각 프로젝트 하위폴더에 생기도록 설정해 주려고 합니다.


[Location 에 Derived Data 설정]


xcode 에서는 build 결과물을 Derived Data 라는 용어로 표현하고 있습니다.

이 부분을 'Relative' 로 변경하면, 프로젝트 하위폴더에 'DerivedData' 라는 이름의 폴더가 생기고 그 안에 결과물이 생성됩니다.


[javah 로 class 파일을 빌드]


JNI 를 만들기 위해서 헤더파일을 생성합니다.

이 부분은 Windows 에서 JNI 를 개발할 때와 동일합니다.

기본적인 내용은 아래 포스트를 참고하시기 바랍니다.


http://crystalcube.tistory.com/66

[jni.h 와 이외에 빌드시 필요한 헤더파일들을 링크시켜 줍니다.]


프로젝트 설정 메뉴 -> build settings 탭을 클릭합니다.

그리고 탭 바로 아래, Basic 을 All 로 변경합니다.

그러면 위 화면처럼 모든 메뉴가 표시됩니다.


Search Paths 부분을 보면, 'User Header Search Paths' 라는 부분이 있습니다.

이 부분에 java 의 jni 헤더들이 있는 폴더를 추가시킵니다.

(만약 그래도 에러가 발생한다면, 'Header Search Paths' 에 등록해 보시기 바랍니다.)

제 경우에는 위 화면의 위치에 jni.h 가 있더군요.



[path 를 지정]


[jni 빌드를 위한 폴더를 추가]




헤더 파일에 선언되 함수를 정의하고 나서 빌드를 합니다.

소스코드가 빠졌는데, 매우 간단한 함수입니다.


그냥 'Hello, world!' 라는 문자열을 리턴하는게 전부입니다.


코드를 구현하고 빌드를 하면, 위에 화면에서처럼 JNI4Mac.dylib 가 생성됩니다.

여담이지만, Windows 에서는 Dynamic Library 확장자가 DLL 인데 반하여,

POSIX  계열 OS 에서는 dylib 를 사용합니다.


그리고 중요한 사실이 하나 있습니다.

JNI 에서 사용하는 dylib 파일은 prefix 로 'lib' 라는 문자열을 붙여야 합니다.


java 에서 

System.loadLibrary("JNI4Mac");

에 상응하는 lib 파일은 'JNI4Mac.dylib' 가 아니라, 'libJNI4Mac.dylib' 가 되어야 한다는 사실입니다.


애초에 xcode 에서 프로젝트를 만들 때, cocoa library 로 제가 만들어 버리는 바람에 'lib' 라는 prefix 가 자동으로 붙지 않았습니다. :)

본래 xcode 에서 빌드하면, 자동으로 lib 가 붙더라고요.

아니면, project 설정에서 prefix 가 자동으로 붙도록 설정하셔도 됩니다.



[Eclipse 에서 실행 위치에 dylib 파일을 복사]






[실행 결과]





jni 작성시, C/C++ 코드를 모두 사용해도 됩니다.

그리고 Cocoa Framework 에 있는 것들을 가져다 써도 됩니다. :)

즉, Objective c 문법을 사용해도 된다는 이야기지요~