Burt.K

코코아를 좋아하는 프로그래머입니다 ;)

JNI 문자열 – 1/3

자바의 String은 유니코드를 기반으로 한다. JNI에서 C/C++로 자바 String 객체를 다루기 위해서 인코딩에 따라 API를 지원한다.

자바 String을 JNI를 통해서 C/C++로 읽기 위해서 아래의 단계를 거친다.

  1. jstring으로 자바 String 인스턴스를 전달받는다.
  2. GetStringUTFChars() 함수로 C/C++로 접근할 수 있는 문자 배열을 만든다. 이 문자열은 UTF-8로 인코딩되고 힙에 동적으로 할당된다.
  3. 2에서 얻은 문자열로 원하는 작업을 한다
  4. ReleaseStringUTFChars() 함수로 힙에 문자열을 위해 할당한 메모리를 해제한다.

인코딩에 따른 JNI문자열 함수는 아래와 같다

함수명을 보면 알 수 있듯이 UTF-8 용 함수에는 UTF라는 명이 함수명에 들어간다.

이 함수를 활용하는 예제로 자바 문자열을 전달받아서 콘솔에 출력하는 예제를 작성해 본다. 

$ vi PrintString.cpp
#include <jni.h>
#include <iostream>

void printString
(
    JNIEnv      *env,
    jobject     thiz,
    jstring     str
)
{
    //convert to c-string from java-string
    //In other words, copy java-string to heap memory on native
    const char *cString = env->GetStringUTFChars(str, nullptr);
    
    std::cout << "c-string is " << cString << std::endl;

    //release heap memory
    env->ReleaseStringUTFChars(str, cString);
    
}

JNIEXPORT jint JNICALL JNI_OnLoad
(
    JavaVM      *vm,
    void        *reserved
)
{
    JNIEnv      *env;
    if(vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) {
        return -1;
    }
    
    JNINativeMethod nm {
        const_cast<char*>("printString"),
        const_cast<char*>("(Ljava/lang/String;)V"),
        reinterpret_cast<void*>(printString)
    };
    
    jclass cls = env->FindClass("Client");
    env->RegisterNatives(cls, &nm, 1);
    return JNI_VERSION_1_6;
}

코드를 컴파일하고 라이브러리로 만든다.

$ g++ "-I/System/Library/Java/JavaVirtualMachines/Current/" -std=c++11 -c PrintString.cpp
$ g++ -dynamiclib -o libprintstring.jnilib printstring.o

이 라이브러리를 사용하는 자바 코드를 작성한다.

$ vi Client.java
public class Client {

    public native void printString(String str);

    public static void main(String[] args) {

        Client client = new Client();
        client.printString("Hello, World!");
    }

    static {
        System.loadLibrary("printstring");
    }
}

컴파일하고 사용해 본다.

$ javac Client.java
$ java Client
c-string is Hello, World!

 

← byte 데이터 주고 받기
JNI 문자열 – 2/3 →