본문 바로가기
개발/JAVA

java에서 JNI 를 이용하여 c 라이브러리(.so,.dll) 사용하기

by Shuming 2017. 10. 15.
반응형


우선 저는 JNI 에 대한 해박한 지식을 갖고 있지 않습니다.


하지만 JNI를 검색하다보니 너무 뻔한 글들이 많아 답답해서 내용을 정리하게 됐습니다.


우선 window에서는 dll 밖에 못씁니다.

그리고 linux에서는 so 파일을 쓸 수 있습니다.

이게 진짜 개빡쳤습니다.


누군가에겐 당연한 얘기겠지만, 저는 이 위 내용을 찾느라 2틀을 뺑이쳤거든여 ㅎ

(참조 - https://stackoverflow.com/questions/34855172/can-we-use-so-files-on-windows) 


제가 핸들링 하고자 하는 제품은 so형태로 library가 제공되었기 때문에, 


이 글에서는 linux 환경에서 so 파일을 핸들링하는 방법을 기재합니다. 

window 환경에서 dll 파일을 핸들링하는 방법은 아래에 간략하게 기재하겠습니다.



1. .so 파일 만들기. (필자는 ubuntu 를 사용했습니다.)


독자들 대부분 so 파일이 없는 경우가 대부분 이시겠죠

저 처럼 so파일이 뭔지도 모르는 분들이 있을겁니다.

.so 는 c라이브러리 파일이라고 알고있습니다. 자세히는 모릅니다.


때문에 저는 gcc 빌더를 이용해서 so파일을 생성을 먼저 하고. 

이후에 so파일을 핸들링 하도록 하겠습니다.


* java가 리눅스에 설치 되어있어야 합니다. (우분투 기준 설치법 - http://ngee.tistory.com/276)


1. c파일 생성 (이놈을 컴파일해서 so로 만들꺼에여)

 - 저는 바탕화면에 폴더 하나 두고 gedit 편집기를 이용해서 작성했습니다.


#include <stdio.h>

#include "HelloWorld.h"


JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)

{

    printf("HelloWorld ");

}



간략하게 HelloWorld를 출력하는 c 입니다. 함수명에 대한 설명은 아래를 참조해주세요.


Java_패키지_랩퍼이름_함수이름__인자(JNIEnv *, jobject, ...)

1. Java는 jni를 사용 했다는 접두어 정도로 보시면 될것 같습니다.

2. 패키지이름은 사용하지 않았으므로 생성되지 않았습니다.

3. 랩퍼이름은 우리가 작성한 Wrapper클래스의 이름이 됩니다.

4. 함수의 이름은 Native블럭에서 작성한 함수의 이름입니다.

5. 마지막으로 _2개를 통해 인자의 키워드가 접미어로 붙는데 현재작성한 

   코드에서는 인자를 받지 않으므로 생성되지 않습니다.

6. 추가적인 인자가 2개 추가됩니다. JNIEnv *와 jobject입니다.

   만약 랩퍼 클래스에서 2개의 인자가있었다면,

   JNIEnv와 jobject가 추가되어 총 4개의 인자를 받는 형태가 됩니다.


출처: http://wowan.tistory.com/115 [DevWarehouse] 




2. java h파일 만들기


c는 이렇게 잠시 두고, java를 짜도록 하겠습니다

또 gedit을 이용해서 HelloWorld.java를 만듭니다. 


그리고 컴파일 합니다.

$ javac HelloWorld.java


그리고 javah를 이용해서 HelloWorld.h 를 만듭니다.

$ javah HelloWorld



c파일을 보고 눈치 채신 분들도 있겠지만 java의 클래스명을 include하고 있구요, 

함수명 또한 맞춰야합니다.


h파일을 보면 알 수 있죠


그런데 함수명이 Java_HelloWorld_print (~~~ 라고 해서 

저걸 다 쓰는게 아니고 그냥 print만 쓰면 돼여


암튼 일단 c 파일에 필요한 헤더파일도 만들어졌고, 컴파일 해봅시다.




3. gcc를 통해 빌드 

- 위에서 참조한 블로그에 이 내용은 좀 더 잘 나와있어여 


 gcc HelloWorld.c -o libHello.so -shared \-I/usr/lib/jvm/java-8-openjdk-amd64/include/ \-I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -fPIC

*요기서 fPIC 옵션을 줘야만 하는데.. 이게 무슨 의미인지는 잘 모르겠습니다.. 동적라이브러리로 사용하는 옵션이라고는 하는데 -shared 도 동적라이브러리 사용하는 옵션이라고 하더군요

대체 무슨 의미인지는 모르겠으나 일단 저렇게 만들었습니다.. 

왜냐면 앞으로 제가 작업할 so 파일은 제가 안만들거든여 헿



아무튼 요로코롬 빌드 하고 나면

이렇게 so 파일이 생깁니다 뿌ㅡ듯



2. Linux 환경에서 .so 파일을 핸들링 하는 법. 


이건 이제 ㅈ밥입니다.


저 라이브러리를 불러오고 있는 HelloWorld.java가 이미 있잖아여?

저거 불러다가 print() 요거 가져오면 됩니다.


이런 useSO 클래스 하나 만들고 HelloWorld 쟤 쓰면 됩니다.

HelloWorld 는 static 에서 so 파일을 불러오고 있는 친구 였구여 


만약 java.lang.UnsatisfiedLinkError: no Hello in java.library.path 이런 에러를 발견 하셨다면.

$ export LD_LIBRARY_PATH=.

를 콘솔에 입력하셔서 현재 폴더를 라이브러리 패스에 추가합니다.




1. .윈도에서 dll 사용법.


so랑 똑같습니다. 다만 dll 파일일 뿐...


so파일 사용하는 것 처럼 static에서 dll 파일 불러오고 함수명 맞춰서 호출만하면 되드라구여..


제가 보여드릴랬는데 어제 소스를 지웟어여 


죄송..;



그럼이만





참조하기 좋은 블로그 


- http://wowan.tistory.com/115

- http://blog.naver.com/PostView.nhn?blogId=matoker&logNo=220515287208&parentCategoryNo=&categoryNo=7&viewDate=&isShowPopularPosts=false&from=postView





반응형

'개발 > JAVA' 카테고리의 다른 글

JPA 1:N 단방향 맵핑  (0) 2022.10.26
Tomcat 에 사설 SSL 적용하기 (https 적용)  (2) 2018.02.13
FileLock FileChannel 공부  (0) 2017.09.30
20일차2 n/1 C/s programming  (0) 2015.12.17
20일차1 c/s programming, TCP통신 복습.  (0) 2015.12.17

댓글