본문 바로가기
자바 코드

JNI로 개발하기 (3. 자바헤더파일 및 C 파일)

by 우딬 2021. 3. 17.

개발 순서

 

1. dll에 있는 함수를 쓰기 위해서 dll의 함수와 똑같은 함수를

자바 코드로 작성하고 dll에 있는 내용을 쓰는식으로 해야한다.

*그래서 자바 코드 작성부터 시작한다.

 

(dll을 불러오는데 자바 코드를 왜 작성하는지 이해를 못해서 한참 책을 몇번을 읽었는지 모른다)

2. 자바 코드 작성 후 자바 헤더를 만들어준다.

3. c에 내가 만든 자바 헤더를 첨부하고 dll을 만들어준다.

4. 자바에서 dll을 읽어준다.

 

 

4. 자바 헤더파일

자바 헤더파일을 한번 열어보자

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnitest_HelloWorld */

#ifndef _Included_jnitest_HelloWorld
#define _Included_jnitest_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jnitest_HelloWorld
 * Method:    show1
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show1
  (JNIEnv *, jobject);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show2
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show2
  (JNIEnv *, jobject, jint);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show3
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show3
  (JNIEnv *, jobject, jintArray);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show4
 * Signature: (C)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show4
  (JNIEnv *, jobject, jchar);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show5
 * Signature: ([C)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show5
  (JNIEnv *, jobject, jcharArray);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show6
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show6__Ljava_lang_String_2
  (JNIEnv *, jobject, jstring);

/*
 * Class:     jnitest_HelloWorld
 * Method:    show6
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show6__
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

 

/*
 * Class:     jnitest_HelloWorld
 * Method:    show2
 * Signature: (I)V
 */

JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show2
  (JNIEnv *, jobject, jint);

 

책에는 JNIEXPORT , JNICALL 이 두코드가 없어도 헤더파일로써의 역활을 한다고한다.
그래서인지 이 두 코드는 신경 쓰지 않고 본다면

 

public native void show2(int i);

 

void Java_jnitest_HelloWorld_show2
  (JNIEnv *, jobject, jint);

 

show2는 int 파라미터가 있었으니 jint가 추가로 적히게된다. (jni에서는 int가 jint로 작성)

 

Signature 는 함수의 형태를 알려주는 기호라고 책에 나와있으나 여러번 만들어봐야 알듯 싶다.

 

5. C 코드 작성

#include "jnitest_HelloWorld.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * Class:     jnitest_HelloWorld
 * Method:    show1
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show1
  (JNIEnv * a, jobject b)
  {
    printf("show1\n");
  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show2
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show2
  (JNIEnv * a, jobject b , jint c)
  {
      printf("show2 : %d \n", c);
  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show3
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show3
  (JNIEnv * a , jobject b, jintArray c)
  {
    jint *A = NULL;
    A = (*a)->GetIntArrayElements(a,c,NULL);
    if(A==NULL)
    {
      printf("error1");
    }
    printf("show3 : %d %d %d \n", A[0], A[1], A[2]);
  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show4
 * Signature: (C)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show4
  (JNIEnv * a, jobject b, jchar c)
  {
    printf("show4 : %c \n", c);
  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show5
 * Signature: ([C)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show5
  (JNIEnv * a, jobject b , jcharArray c)
  {
    jchar *A = NULL;
    A = (*a)->GetCharArrayElements(a,c,NULL);
    if(A==NULL)
    {
      printf("error2");
    }
    printf("show5 : %c %c %c \n", A[0], A[1], A[2]);
  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show6
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show6__Ljava_lang_String_2
  (JNIEnv * a, jobject b, jstring c)
  {
      char strbuf[128];
      const char *sz = (*a)-> GetStringUTFChars(a,c,0);
      strcpy(strbuf,sz);
      printf("show6 : %s\n", strbuf );
      (*a)->ReleaseStringUTFChars(a,c,sz);

  }

/*
 * Class:     jnitest_HelloWorld
 * Method:    show6
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jnitest_HelloWorld_show6__
  (JNIEnv * a, jobject b)
  {
    jclass cls = (*a)->GetObjectClass(a,b);

    jmethodID funcM = (*a)->GetMethodID(a,cls,"func","()V");
    if(funcM == 0)
    {
        printf("Method Func ?? \n");
    }
    else
    {
      printf("Method func ok ... \n");
      (*a)->CallVoidMethod(a,b,funcM);
    }
  }

 

헤더가 있는 곳에 C파일을 작성합니다.

 

show1 : 단순히 show1을 출력하는 함수입니다.

show2 : int 파라미터로 show2 : int 를 출력합니다.

show3 : intArray값을 3개 출력한다.

show4 : char 값을 1개 출력한다.

show5 : charArray값을 3개 출력한다.
show6(String a) : a 문자값을 출력한다.
show6() : func함수 내용을 보여준다.

 

이 파일을 작성한 후 컴파일 해보자

댓글