JAVA

Java와 C/C++의 연동 관련, JNI

AlrepondTech 2020. 9. 18. 02:23
반응형

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://www.iamcorean.net/95

작성자 : 김문규
최초 작성일 : 2008. 9. 5

JNI는 Java 클래스에서 C 라이브러리를 호출하는 기술입니다.

구현 방법은 다음과 같습니다.

1. Java 클래스 구현

HelloJniClass.java

public class HelloJniClass {

    native void Hello(); // native 함수
    static {
        System.loadLibrary("Hello_DLL");
    } // 로드할 라이브러리 Hello_DLL.dll 을 로드합니다.

    public static void main(String args[]) {
        HelloJniClass myJNI = new HelloJniClass();
        myJNI.Hello(); // native 함수 호출
    }
}

 

> javac HelloJniClass.java
HelloJniClass.class 파일 생성됩니다.


2. C용 헤더 파일 생성
> javah HelloJniClass
HelloJniClass.h 가 생성됩니다. 이 파일은 구현해야 할 함수가 선언되어 있습니다.
클래스패스 선언에 유의합니다. (간단하게는 같은 폴더에 놓고 -classpath . 하면 됩니다.)


3. dll 파일 생성
HelloJniClass.h를 이용해서 원하는 기능을 수행하는 dll 파일을 작성합니다.

HelloWorldLib.cpp

#include "stdafx.h"

#include <stdio.h>

#include "jni.h"

#include "HelloJniClass.h"

JNIEXPORT void JNICALL Java_HelloJniClass_Hello(JNIEnv * env, jobject jobj) {
    printf("Hello Jni~!"); // 원하는 기능
}

 

컴파일 하시면 Hello_DLL.dll 이 생성됩니다.
비줠 스튜디오에서 output 파일 이름을 맞추는 설정을 하시고 프로젝트 include 폴더에 (JDK_HOME)/include/win32를 추가합니다.


4. 실행
> java HelloJniClass
(역시나 클래스패스 설정에 유의하시길 바랍니다.)
Hello Jni~!

5. 완벽한 가이드 문서
 

JNI.pdf
0.26MB

 

 

 

 

=======================

=======================

=======================

 

 



jni (c<->jaVA) 연동  

1. 필요한 파일들.

 

1.1. NativeStringUtil.c (스트링 변환 함수)

#include <stdlib.h>

#include <jni.h>

#include "NativeStringUtil.h"

/* 효율성을 높이기 위한 캐슁 변수 */
static jclass class_String;
static jmethodID mid_getBytes, mid_getBytesEncoding;
static jmethodID mid_newString, mid_newStringEncoding;

/* C 문자열로부터 자바 바이트 배열을 생성하여 반환
 */
jbyteArray cstr2jbyteArray(JNIEnv * env,
    const char * nativeStr) {
    jbyteArray javaBytes;
    int len = strlen(nativeStr);
    javaBytes = ( * env) - > NewByteArray(env, len);
    ( * env) - > SetByteArrayRegion(
        env, javaBytes, 0, len, (jbyte * ) nativeStr);
    return javaBytes;
}

/* 자바 바이트 배열로부터 C 문자열을 생성하여 반환
 */
char * jbyteArray2cstr(JNIEnv * env, jbyteArray javaBytes) {
    size_t len = ( * env) - > GetArrayLength(env, javaBytes);
    jbyte * nativeBytes = ( * env) - > GetByteArrayElements(env, javaBytes, 0);
    char * nativeStr = malloc(len + 1);

    strncpy(nativeStr, nativeBytes, len);
    ( * env) - > ReleaseByteArrayElements(env, javaBytes, nativeBytes, JNI_ABORT);
    return nativeStr;
}

/* 자바 스트링을 디폴트 인코딩의 자바 바이트 배열로 변환.
 * String 클래스의 getBytes() 메쏘드를 호출한다.
 */
jbyteArray javaGetBytes(JNIEnv * env, jstring str) {
    if (mid_getBytes == 0) {
        if (class_String == 0) {
            jclass cls = ( * env) - > FindClass(env, "java/lang/String");
            if (cls == 0)
                return 0; /* 오류 */
            class_String = ( * env) - > NewGlobalRef(env, cls);
            if (class_String == 0)
                return 0; /* 오류 */
        }
        mid_getBytes = ( * env) - > GetMethodID(
            env, class_String, "getBytes", "()[B");
        if (mid_getBytes == 0)
            return 0;
    }

    /* str.getBytes(); */
    return ( * env) - > CallObjectMethod(env, str, mid_getBytes);
}

/* 자바 스트링을 지정된 인코딩 `encoding'의 자바 바이트 배열로 변환.
 * String 클래스의 getBytes(String encoding) 메쏘드를 호출한다.
 */
jbyteArray javaGetBytesEncoding(JNIEnv * env, jstring str,
    const char * encoding) {
    if (mid_getBytesEncoding == 0) {
        if (class_String == 0) {
            jclass cls = ( * env) - > FindClass(env, "java/lang/String");
            if (cls == 0)
                return 0; /* 오류 */
            class_String = ( * env) - > NewGlobalRef(env, cls);
            if (class_String == 0)
                return 0; /* 오류 */
        }
        mid_getBytesEncoding = ( * env) - > GetMethodID(env, class_String, "getBytes", "(Ljava/lang/String;)[B");
        if (mid_getBytesEncoding == 0)
            return 0;
    }

    /* str.getBytes( encoding ); */
    return ( * env) - > CallObjectMethod(env, str, mid_getBytesEncoding, ( * env) - > NewStringUTF(env, encoding));
}

/* 디폴트 인코딩의 자바 바이트 배열을 자바 스트링으로 변환.
 * String 클래스의 new String(byte[] bytes) 메쏘드를 호출한다.
 */
jstring javaNewString(JNIEnv * env, jbyteArray javaBytes) {
    if (mid_newString == 0) {
        if (class_String == 0) {
            jclass cls = ( * env) - > FindClass(env, "java/lang/String");
            if (cls == 0)
                return 0; /* 오류 */
            class_String = ( * env) - > NewGlobalRef(env, cls);
            if (class_String == 0)
                return 0; /* 오류 */
        }
        mid_newString = ( * env) - > GetMethodID(
            env, class_String, "<init>", "([B)V");
        if (mid_newString == 0)
            return 0;
    }

    /* new String( javaBytes ); */
    return ( * env) - > NewObject(
        env, class_String, mid_newString, javaBytes);
}

/* 지정된 인코딩 `encoding'의 자바 바이트 배열을 자바 스트링으로 변환.
 * String 클래스의 new String(byte[] bytes, String encoding)
 * 메쏘드를 호출한다.
 */
jstring javaNewStringEncoding(
    JNIEnv * env, jbyteArray javaBytes,
    const char * encoding) {
    int len;
    jstring str;

    if (mid_newString == 0) {
        if (class_String == 0) {
            jclass cls = ( * env) - > FindClass(env, "java/lang/String");
            if (cls == 0)
                return 0; /* 오류 */
            class_String = ( * env) - > NewGlobalRef(env, cls);
            if (class_String == 0)
                return 0; /* 오류 */
        }
        mid_newString = ( * env) - > GetMethodID(
            env, class_String, "<init>", "([BLjava/lang/String;)V");
        if (mid_newString == 0)
            return 0;
    }

    /* new String( javaBytes, encoding ); */
    str = ( * env) - > NewObject(
        env, class_String, mid_newString, javaBytes,
        ( * env) - > NewStringUTF(env, encoding));
    return str;
}

 

 

 

1.2. NativeStringUtil.h

#ifndef _Included_NativeStringUtil
#define _Included_NativeStringUtil
#ifdef __cplusplus
extern "C" {
#endif
char *jbyteArray2cstr( JNIEnv *env, jbyteArray javaBytes );
jbyteArray cstr2jbyteArray( JNIEnv *env, const char *nativeStr);
jbyteArray javaGetBytes( JNIEnv *env, jstring str );
jbyteArray javaGetBytesEncoding( JNIEnv *env, jstring str, const char *encoding );

jstring javaNewString( JNIEnv *env, jbyteArray javaBytes );
jstring javaNewStringEncoding(JNIEnv *env, jbyteArray javaBytes, const char *encoding );
#ifdef __cplusplus
}
#endif
#endif

1.3. com_pepsi_user_decode_JDecode.c
 - javah -jni 통해 만든 header파일을 재구성해 줌. 
 

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

#include <com_pepsi_user_decode_JDecode.h>

#include "NativeStringUtil.h"

#include "Decode.h"

#define BUFSIZE 1024

/*
 * Class:     JDecode
 * Method:    decodeString
 * Signature: (ILjava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jstring JNICALL Java_com_pepsi_user_decode_JDecode_nativeDecodeStr
    (JNIEnv * env, jobject jobj, jstring tar) {
        char cSource[BUFSIZE];
        int iCoopNum = 1;
        int rt;
        const char * cTarget;
        cTarget = jbyteArray2cstr(env, javaGetBytesEncoding(env, tar, "EUC-KR"));

        bzero(cSource, sizeof(cSource));
        rt = decodeString(cTarget, cSource); // 복호화 함수
        ( * env) - > ReleaseStringUTFChars(env, tar, cTarget);

        return javaNewStringEncoding(env, cstr2jbyteArray(env, cSource), "EUC-KR");
    }

1.4.com_pepsi_user_decode_JDecode.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>

/* Header for com_pepsi_user_decode_JDecode */

#ifndef _Included_com_pepsi_user_decode_JDecode
#define _Included_com_pepsi_user_decode_JDecode
#ifdef __cplusplus
extern "C" {
    #endif

    /*
     * Class:     com_pepsi_user_decode_JDecode
     * Method:    nativeDecodeStr
     * Signature: (Ljava/lang/String;)Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_pepsi_user_decode_JDecode_nativeDecodeStr
        (JNIEnv * , jobject, jstring);
    #ifdef __cplusplus
}
#endif
#endif

 

1.5 Decode.h
 - 복호화 헤더 파일.

 

1.6 testCipher.c
 - 복호과 구현 파일.

 

2. so 파일 생성.
  - 내용 : 특정 스트링 복호화 하는 라이브러리.
  - libDecode.so

 

2.1 간단한 Makefile

CC=/usr/bin/gcc
CFLAGS=-D_REENTRANT -D_GNU_SOURCE

JNIFLAGS=-I/k2/src/jni/cookie -I/usr/local/j2sdk1.4.2_04/include -I/usr/local/j2sdk1.4.2_04/include/li
nux
OBJS = ./cipher/testCipher.o com_pepsi_user_decode_JDecode.o NativeStringUtil.o
TARGET =  libDecode.so

$(TARGET): $(OBJS)
    $(CC) -shared -o $@ $(OBJS)

all : $(TARGET)

install :
    mv libDecode.so /usr/lib

clean :
    \rm -rf *.o *.a *.so

.SUFFIXES: .c .o

.c.o:
    $(CC) $(CFLAGS) $(JNIFLAGS) -c -o $@ $<

 

3. JDecode.java

package com.pepsi.user.decode;
// 패키지 명은 위의 라이브러리 
// com_pepsi_user_decode_JDecode.h 와 일치해야 
// 일치 안하면 java.lang.UnsatisfiedLinkError 발생한다.

public class JDecode {

    static {
        System.loadLibrary("Decode"); // load(libDecode.so)도 있다
    }

    public native String nativeDecodeStr(String psTarget);

}

 

4. 사용방법
 - libDecode.so LD_LIBRARY_PATH혹은 /usr/lib에 카피.
 - String decode = new JDecode().nativeDecodeStr(encode);



 

 

=======================

=======================

=======================

 

 

 

 

반응형

 

 

728x90

 

 



출처: http://sinuk.egloos.com/2676307

 

1. JNI (Java Native Interface) 란 ?

- 자바가 다른 언어로 만들어진 어플리케이션과 상호 작용할 수 있는 인터페이스를 제공한다.

- 자바가상머신(JVM)이 원시 메소드(native method)를 적재(locate)하고 수행(invoke)할 수 있도록 한다

- JNI가 자바가상머신내에 포함됨으로써, 자바가상머신이 호스트 운영체제상의 입출력, 그래픽스, 네트워킹, 그리고 스레드와 같은 기능들을 작동하기 위한 로컬시스템호출(local system calls)을 수행할 수 있도록 한다. 

* 쉽게 말해 Java와 다른 언어를 연동하는 솔루션입니다.

 

[그림1] C로 만들어진 Library와 JAVA를 연결해주는 JNI

 

 

2. Why do you need JNI ?

 

자 바 네이티브 메쏘드(Java Native method, 이하 JNI)는 다른 언어로 작성된 코드를 자바에서 호출하도록 만들어진 규약이다. 현재는 C/C++에 대한 호출만을 정확하게 지원한다. 어떻게 보면 JNI는 자바가 만들어진 철학과 정반대되는 것이다.

 

그러나. Java에도 한계가 있다.

 

1. 속도 문제가 있는 계산 루틴 
 > 자바가 Native Code(플랫폼에 종속적인 기계어 코드)에 비해 느리다.

2. 자바에서 하드웨어 제어 

3. 자바에서 지원되지 않은 특정 운영체제 서비스 
 > 자바의 클래스 라이브러리는 방대하고 다양한 서비스를 제공하지만, 특정 플랫폼에서 제공하는 고유의 서비스의 기능을 모두 포함할  수는 없다. 특히, 특수한 목적으로 제작된 하드웨어를 자바에서 제어해야 할 필요가 있다고 한다면, 자바만으로 해결하기는 힘들다. 

4. 기존의 프로그램에서 자바가 제공하는 서비스를 이용 
 > 기존에 작성된 프로그램이나 기존의 시스템(legacy)과의 연계 문제

 

∴ JNI를 써서 해결해보

3. C를 이용한 JNI 예제

VC++을 이용해 C문법으로 작성되어 만들어진 DLL을 로딩하여 Java에서 사용해보겠습니다.

 

1단계 : Native Method를 선언하는 자바 클래스 작성
2단계 : 1단계에서 작성한 클래스 컴파일
3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성
4단계 : C언어로 Native Method 실제 구현
5단계 : C 코드와 헤더 파일을 컴파일
6단계 : 자바 프로그램 실행


 

1단계 : Native Method를 선언하는 자바 클래스 작성

Java 소스 파일 : HelloJni_Jsource.java

import java.util.*;

class HelloJniClass {
   native void Hello();

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

  public static void main(String args[]) {    
      HelloJniClass myJNI=new HelloJniClass();
      myJNI.Hello();
   }
}

 

// 아래는 좀 위의 내용 보충 그림

 

2단계 : 1단계에서 작성한 클래스 컴파일



* 컴파일시에는 일반 java 컴파일때와 마찬가지로 환경변수 셋팅이 되어 있어야 합니다.
 -> Path가 JDK의 Javac.exe가 있는 폴더에 설정되어 있어야 합니다.

 

 

3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성

 

 

HelloJniClass.h을 열어보면

JNIEXPORT void JNICALL Java_HelloJniClass_Hello  (JNIEnv *, jobject);
위의 함수를 Implement만 해서 DLL을 만들면 됩니다. (4단계)


4단계 : C언어로 Native Method 실제 구현(1)

1) VC++ 프로젝트 만들기 : Win32용 DLL 프로젝트로 만듭니다.
New - Projects : Win32 Dynamic-Link Library 

2) Add Files Projects : HelloJniClass.h 파일 추가

3) Projects Setings(Alt+F7)
   - Link탭에 Output file Name : 1단계의 2. 라이브러리 적재시 작성한 DLL파일명(Hello_DLL.dll)
   - C/C++탭 Preprocessor 카테고리의 Additional Include directories 
       JDK의 Include폴더와 Include폴더 밑의 win32폴더

          예) C:\Program Files\Java\jdk1.5.0_03\include\, 
             C:\Program Files\Java\jdk1.5.0_03\include\win32

 

 

4. 값의 전달과 리턴

 

1단계 : Java 소스 파일 StringPass_Jsource.java
* 일반 자바 메쏘드 선언과 동일합니다.

class JNI_Message {
   native byte[] Message(String input);

  // 라이브러리 적재(Load the library)  

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



  public static void main(String args[]) {    
 byte buf[];

    // 클래스 인스턴스 생성(Create class instance)
    JNI_Message myJNI=new JNI_Message();

    // 원시 메소드에 값을 주고 받음
    buf = myJNI.Message("Apple");
 
 System.out.print(buf); // 받은값 출력
 }
}

 


2단계 : 컴파일
 javac StringPass_Jsource.java

 

3단계 : header파일 생성
 javah JNI_Message

 

4단계 : method구현 : StringJNIDLLSource.c

#include <stdio.h>
#include <jni.h>
#include <string.h>
#include "JNI_Message.h"

JNIEXPORT jbyteArray JNICALL Java_JNI_1Message_Message (JNIEnv * env, jobject jobj, jstring input) 
{
    jbyteArray jb;
    jboolean iscopy;
    char* buf;
    static char outputbuf[20];

    buf=(*env)->GetStringUTFChars(env, input, &iscopy);  // 입력 String 읽어오는 함수
    printf ("\nDLL receive Data from JAVA : %s\n",buf);   // 입력받은 내용을 출력
    strcpy(outputbuf,"Delicious !!\n"); 
    jb=(*env)->NewStringUTF(env, outputbuf);  // 출력할 내용의 java버퍼에 output버퍼값을 셋팅

   return(jb); // java버퍼 리턴
}

 

(*env)->함수명 형태로, JAVA의 메쏘드를 C에서 이용할수 있습니다.
* JAVA는 C로 문자열을 넘겨줄때 UTF-8형태를 사용합니다.

 

5단계 : 실행

C:\test\C_JNI\Paramerter Pass>java JNI_Message

DLL receive Data from JAVA : Apple
Delicious !!


5. KVM ? KNI ?

KVM은 J2ME의 일부로서 작고 자원이 한정된 기계장치를 위해 설계된 소형 JVM.
JVM에서는 JNI가 KVM의 KNI가 있다.


 

6. 기타프로그래밍 이슈들
참고 URL :http://www.javastudy.co.kr/docs/jhan/javaadvance/jni.html

언어적 이슈(Language Issues) 
메소드 호출(Calling Methods) 
필드의 참조(Accessing Fields) 
스레드와 동기화(Threads and Synchronization) 
메모리 이슈(Memory Issues) 
수행(Invocation) 
스레드 연결(Attaching Threads) 

 

 

 

=======================

=======================

=======================

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=nadia407&logNo=80120508458

 

JNI_정리.cpp
0.01MB
JNIExample.pdf
0.18MB

 

 

 

 

=======================

=======================

=======================

 

 


 

- AntiStroy 님의 블러그에서 퍼왔음을 알립니다.

프로젝트를 진행하면서 JNI에 대해 알게 되었었다. Java에서 C함수를 호출하거나 C에서 Java의 메소드를 호출할 때 사용하는 것인데, 안드로이드 공부를 하다가 조금 더 파고들게 되었다. 

* 안드로이드는 자바로 프로그래밍을 하는데 왜 JNI에 대해 알아야 할까?
우선 안드로이드 플랫폼은 순수하게 Java로만 구성되어진 것이 아닌 Java 레이어와 C/C++레이어가 서로 상호 작용하면서 동작한다. 이 두 레이어가 유기적으로 동작하게 만들려면 JNI에 대해 알아야 한다. 
그리고 일반적으로 Java는 C/C++에 비해 느리다. 성능이 중요할 경우 C/C++로 작성하고 이를 JNI를 통해 Java에서 호출할 수 있다.

* NDK(Native Development Kit)
안드로이드 애플리케이션에서 사용할 네이티브 라이브러리를 작성하기 위한 도구 모음.
실제로 모듈을 구현하기 위해서는 JNI에 대한 지식 필요

* JNI의 개발 순서
1. Java 코드 작성
2. Java 코드 컴파일
3. C 헤더 파일 생성
4. C 코드 작성
5. C 공유 라이브러리 생성
6. Java 프로그램 실행

1. Java 코드 작성


public class AtinJNI {
    // 네이티브 메소드 선언 

    native void printAtin();

    native void printString(String str);

    // 라이브러리 로딩

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

    public static void main(String args[]) {

        AtinJNI myJNI = new AtinJNI();

        // 네이티브 메소드 호출

        myJNI.printAtin();

        myJNI.printString("Hello Atin");

    }

}

[Source 1] AtinJNI.java

[표 1] 플랫폼별 System.loadLibrary() 메소드가 로딩하는 C라이브러리 형식

 호스트 플랫폼  실제 로드되는 C 라이브러리 
 Window   libname.dll 
 Linux   libname.so 



2. Java 코드 컴파일
javac를 통해서 .java파일을 .class로 컴파일한다.

 javac AtinJNI.java


위와 같은 명령을 실행할 경우 아무 에러가 나지 않는다면 .class로 컴파일 된 것이다.

3. C 헤더 파일 생성
이제 Java 소스를 만들었으니 C 소스를 짜야 한다. 그런데 중요한 점은 어떻게 Java에서 호출되는 C 소스를 짤 것인가이다. 이것을 위해 javah라는 툴이 있다. 이 툴을 사용하면 .class파일을 파싱해서 만들어야 할 C 함수의 헤더를 만들어준다. 

javah <native로 선언된 메소드를 포함한 자바 클래스명>
- <JDK_HOME>\bin에 포함.
- Java 네이티브 메소드와 연결될 수 있는 C함수의 원형 생성

 javah AtinJNI

위와 같은 명령어를 실행하면 AtinJNI.h라는 헤더 파일이 생성됀다.

내용은 아래와 같다.

 


 

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

/* Header for class AtinJNI */

#ifndef _Included_AtinJNI

#define _Included_AtinJNI

#ifdef __cplusplus

extern "C" {

    #endif

    /*

     * Class:     AtinJNI

     * Method:    printHello

     * Signature: ()V

     */

    JNIEXPORT void JNICALL Java_AtinJNI_printHello

        (JNIEnv * , jobject);

    /*

     * Class:     AtinJNI

     * Method:    printString

     * Signature: (Ljava/lang/String;)V

     */

    JNIEXPORT void JNICALL Java_AtinJNI_printString

        (JNIEnv * , jobject, jstring);

    #ifdef __cplusplus

}

#endif

#endif

 


 

[Source 2] AtinJNI.h

4. C 코드 작성
위에서 생성한 AtinJNI.h의 헤더를 기준으로 C 소스를 작성하면 됀다. 

 


 

#include "HelloJNI.h"

#include <stdio.h>


JNIEXPORT void JNICALL Java_AtinJNI_printAtin

    (JNIEnv * env, jobject obj)

{

    printf("Hello Atin \n");

    return;

}

JNIEXPORT void JNICALL Java_AtinJNI_printString

    (JNIEnv * env, jobject obj, jstring string)

{

    const char * str = ( * env) - > GetStringUTFChars(env, string, 0);

    printf("%s! \n", str);

    return;

}

 


 

[Source 3] atinjni.c

5. C 공유 라이브러리 생성
중요한건 Window는 dll, Linux는 so파일을 만들어야 한다. 책에서는 C 소스를 작성 후 cl명령을 통해 dll을 만들었다.

cl 명령은 Visual Studio 2008 명령 프롬프트에서 실행해야 하며 VC 2008 Express Editions(http://www.microsoft.com/express/download/)가 설치되어 있어야 한다.

cl -I"<JDK_HOME>\include" -I"<JDK_HOME>\include\win32" -LD atinjni.c -Featinjni.dll
cl : vc++ 컴파일 명령어
-I<dir> : 헤더 파일을 검색할 디렉토리 경로 <dir> 추가
-LD : DLL 생성
-FE<파일명> : 컴파일 결과 파일 이름 지정

나는 VC에서 직접하고 싶어서 [1]과 같이 dll을 만들었다.
그런데 다음과 같은 문제에 직면했다.

 


Can't load IA 32-bit .dll on a AMD 64-bit platform
그래. 나는 64비트용 윈도우 7 운영체제였 다. 32비트 dll이 문제가 되는 것이었다. 구글링해보니 32비트용으로 Java를 다시 까니 실행 명령어에 옵션을 주는 몇 방법들이 있었는데 마음에 들지 않았다. dll을 64비트용으로 하면 될 것 같았다. 그래서 [2]와 같은 방법으로 dll을 64비트용으로 만들어주었고 문제를 해결했다.

6. Java 프로그램 실행
이클립스라면 그냥 실행하면 되고 콘솔에서라면 "java AtinJNI"로 실행하면 결과를 볼 수 있다.

Reference
[1] VC에서 DLL 만드는 방법 (http://sol9501.blog.me/70102942944)
[2] 64비트용 컴파일 (http://blog.naver.com/PostView.nhn?blogId=honnak&logNo=70085595801&viewDate=¤tPage=1&listtype=0
[3] 인사이드 안드로이드(Inside the Android Framework, 위키북스)

 

 

 

=======================

=======================

=======================

 

 

반응형