Java에서 C 프로그램을 연동해 실행하려고 합니다.
Java에서 C 프로그램을 연동해 실행하려면 JNI가 필요하다고 하던데요. JNI 를 사용하기 위해 어떤 패키지를 받아야 하나요. 현재 fedora17을 사용하고 있습니다. 그리고 javah라는 실행파일은 있고요. 현재 상태에서 다음과 같이 소스를 만들고 컴파일 해봤지만 C의 프로그램이 실행되지 않습니다.
-HelloNative.java-
public class HelloNative {
native public void hello();
static {
try {
System.loadLibrary("HelloNative");
}
catch(UnsatisfiedLinkError ex) {}
}
public static void main(String[] args) {
try {
HelloNative my_native=new HelloNative();
my_native.hello();
}
catch(UnsatisfiedLinkError ex) {}
}
}
그리고 다음과 같이 컴파일하고 헤더를 만들었습니다.
java HelloNative.java
javah HelloNative
그리고 다음과 같이 동적으로 실행될 c 파일을 만들었습니다.
#include "HelloNative.h"
//#include
#include
using namespace std;
JNIEXPORT void JNICALL Java_HelloNative_hello(JNIEnv *, jobject) {
//printf("%s","The referenced C code.");
cout<<"The referenced C code"<
return;
}
그리고 다음과 같은 방식으로 목적파일과 동적실행파일을 만들었습니다.
g++ -c -fPIC -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9/include -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9/include/linux HelloNative.c
g++ -shared -o libHelloNative.so HelloNative.o
그리고 마지막으로 다음과 같이 실행
java HelloNative
그러나
The referenced C code
위의 구문이 cout 으로 출력되지 않습니다.


JNI 사용하기
참고로 윈도우용 Jni 사용 및 윈도우 패키지 만들기 첨부 https://docs.google.com/presentation/d/1y0_pFM2O1UIzL5CopJQDoxgrNAOH7lAwPg7KNIv7GqI/edit // VirtualBox 페도라13 확인 //문의 내용 http://kldp.org/node/135417 //JNI 사용하기 http://blog.naver.com/heartwork99?Redirect=Log&logNo=30151525974 //------------------------------------------------------------------------------------------------------------------------ //JDK-7u10-linux-i586.rpm 다운로드 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html //rpm -ivh 설치 http://www.cyworld.com/ruo91/3459378 그냥은 에러나고. su - 엔터 치고. 암호 넣어서. 관리자 권한으로 설치해야 함. // 설치시 다될때쯤에. 에러남. [root@localhost Downloads]# rpm -ivh jdk-7u10-linux-i586.rpm Preparing... ########################################### [100%] 1:jdk ########################################### [100%] Unpacking JAR files... rt.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/rt.pack jsse.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/jsse.pack charsets.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/charsets.pack tools.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/lib/tools.pack localedata.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/ext/localedata.pack plugin.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/plugin.pack javaws.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/javaws.pack deploy.jar... Error: Could not open input file: /usr/java/jdk1.7.0_10/jre/lib/deploy.pack 그냥 무시하고 넘어감... 걍 됨. ㅡ_ㅡ;;; //------------------------------------------------------------------------------------------------------------------------ 아무 폴더나 생성하고. 파일 생성함. 나는 test10 //------------------------------------------------------------------------------------------------------------------------ //cpp와 cout은 C++라는 말임. 컴파일러도 g++를 써야 함. (.c는 gcc로 컴파일) // //------------------------------------------------------------------------------------------------------------------------ //HelloNative.cpp #include "HelloNative.h" #include <iostream> using namespace std; JNIEXPORT void JNICALL Java_HelloNative_hello( JNIEnv *, jobject ) { cout << "The referenced C code" << endl; } //------------------------------------------------------------------------------------------------------------------------ //이건 javah로 생성되는 네이티브 인터페이스용 코드 헤더임. // //HelloNative.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloNative */ #ifndef _Included_HelloNative #define _Included_HelloNative #ifdef __cplusplus extern "C" { #endif /* * Class: HelloNative * Method: hello * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloNative_hello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif //------------------------------------------------------------------------------------------------------------------------ //HelloNative.Java public class HelloNative { native public void hello(); static { try { System.loadLibrary("HelloNative"); } catch(UnsatisfiedLinkError ex) { } } public static void main(String[] args) { try { HelloNative my_native = new HelloNative(); my_native.hello(); } catch(UnsatisfiedLinkError ex) { } } } //------------------------------------------------------------------------------------------------------------------------ //모두 작성했으면. //이대로 치면 됨. javac HelloNative.java /usr/java/jdk1.7.0_10/bin/javah -jni HelloNative g++ -c -fPIC -I/usr/java/jdk1.7.0_10/include -I/usr/java/jdk1.7.0_10/include/linux HelloNative.cpp g++ -shared -o libHelloNative.so HelloNative.o export LD_LIBRARY_PATH=./ g++ -shared -o libHelloNative.so HelloNative.cpp -fPIC -I/usr/java/jdk1.7.0_10/include -I/usr/java/jdk1.7.0_10/include/linux java HelloNative Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloNative : Unsupported major.minor version 51.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:632) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:277) at java.net.URLClassLoader.access$000(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:212) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:205) at java.lang.ClassLoader.loadClass(ClassLoader.java:319) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) at java.lang.ClassLoader.loadClass(ClassLoader.java:264) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:332) Could not find the main class: HelloNative. Program will exit. //버젼이 안맞는다고. 에러 남. //java.lang.UnsupportedClassVersionError http://blog.naver.com/jwjanguis?Redirect=Log&logNo=70037808263 http://blog.naver.com/innocent_11?Redirect=Log&logNo=171452181 http://blog.naver.com/kazki7074?Redirect=Log&logNo=120049193440 //자바 버전 확인하기 0~ 51 Unsupported Class Version 이니까. 맞는 버전을 찾으면 됨. 클래스가 역컴파일이 되서 보이네... 헐 ㅡ_ㅡ;;; 이거 하라고 시키는듯이 말이다. [shint@localhost test10]$ /usr/java/jdk1.7.0_10/bin/javap -verbose HelloNative Classfile /home/shint/test10/HelloNative.class Last modified Dec 16, 2012; size 571 bytes MD5 checksum 6711c00a5676ebbe01afc7a66b32cd8e Compiled from "HelloNative.java" public class HelloNative SourceFile: "HelloNative.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #8.#21 // java/lang/Object."<init>":()V #2 = Class #22 // HelloNative #3 = Methodref #2.#21 // HelloNative."<init>":()V #4 = Methodref #2.#23 // HelloNative.hello:()V #5 = Class #24 // java/lang/UnsatisfiedLinkError #6 = String #22 // HelloNative #7 = Methodref #25.#26 // java/lang/System.loadLibrary:(Ljava/lang/String;)V #8 = Class #27 // java/lang/Object #9 = Utf8 <init> #10 = Utf8 ()V #11 = Utf8 Code #12 = Utf8 LineNumberTable #13 = Utf8 hello #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Utf8 StackMapTable #17 = Class #24 // java/lang/UnsatisfiedLinkError #18 = Utf8 <clinit> #19 = Utf8 SourceFile #20 = Utf8 HelloNative.java #21 = NameAndType #9:#10 // "<init>":()V #22 = Utf8 HelloNative #23 = NameAndType #13:#10 // hello:()V #24 = Utf8 java/lang/UnsatisfiedLinkError #25 = Class #28 // java/lang/System #26 = NameAndType #29:#30 // loadLibrary:(Ljava/lang/String;)V #27 = Utf8 java/lang/Object #28 = Utf8 java/lang/System #29 = Utf8 loadLibrary #30 = Utf8 (Ljava/lang/String;)V { public HelloNative(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public native void hello(); flags: ACC_PUBLIC, ACC_NATIVE public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: new #2 // class HelloNative 3: dup 4: invokespecial #3 // Method "<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method hello:()V 12: goto 16 15: astore_1 16: return Exception table: from to target type 0 12 15 Class java/lang/UnsatisfiedLinkError LineNumberTable: line 19: 0 line 20: 8 line 24: 12 line 22: 15 line 25: 16 StackMapTable: number_of_entries = 2 frame_type = 79 /* same_locals_1_stack_item */ stack = [ class java/lang/UnsatisfiedLinkError ] frame_type = 0 /* same */ static {}; flags: ACC_STATIC Code: stack=1, locals=1, args_size=0 0: ldc #6 // String HelloNative 2: invokestatic #7 // Method java/lang/System.loadLibrary:(Ljava/lang/String;)V 5: goto 9 8: astore_0 9: return Exception table: from to target type 0 5 8 Class java/lang/UnsatisfiedLinkError LineNumberTable: line 8: 0 line 12: 5 line 10: 8 line 13: 9 StackMapTable: number_of_entries = 2 frame_type = 72 /* same_locals_1_stack_item */ stack = [ class java/lang/UnsatisfiedLinkError ] frame_type = 0 /* same */ } [shint@localhost test10]$ //여기 보니 환경 변수 넣으라고 함. http://blog.naver.com/innocent_11?Redirect=Log&logNo=171452181 //환경 변수 넣기 귀찮으니. 그냥 절대 경로 넣어주고 실행하면 됨. [shint@localhost test10]$ g++ -shared -o libHelloNative.so HelloNative.cpp -fPIC -I/usr/java/jdk1.7.0_10/include -I/usr/java/jdk1.7.0_10/include/linux [shint@localhost test10]$ /usr/java/jdk1.7.0_10/bin/java HelloNative The referenced C code 아까 export LD_LIBRARY_PATH=./ 가 그와 같은 역할을 하는걸로 보임. 근데. 나는 잘 안됨. ㅡ_ㅡ;;; 하튼. 성공.----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기