Guest User

Untitled

a guest
Mar 24th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.41 KB | None | 0 0
  1. # SWIG C and JAVA
  2.  
  3.  
  4.  
  5. (작성중)
  6.  
  7.  
  8.  
  9. SWIG는 기존에 작성된 C 또는 C++ 라이브러리를 다양한 언어에 포팅하는데 사용되는 도구이다. 이 글에서는 C 라이브러리를 JAVA와 연결하는데 필요한 정보를 정리한다. 이 글에서 C 라이브러리의 이름은 mylib 라고 가정한다.
  10.  
  11.  
  12.  
  13. ## 구현 흐름
  14.  
  15.  
  16.  
  17. mylib.c, mylib.h 작성 -> mylib.i SWIG 중간 언어 작성 -> mylib.i를 swig로 변환 -> libmylib.so 빌드 -> libmylib_java.so 빌드 -> Java에서 사용 및 테스트
  18.  
  19. _
  20.  
  21. 흐름이 굉장히 길고, 한 프로세스는 이전 프로세스에 영향을 받는다. 따라서 mylib.h에 변경이 하나라도 생기면 나머지 모든 작업을 다시 테스트 해봐야 한다. **mylib.h에서 제공하는 API가 충분히 고정되었을 때** SWIG 컨버팅을 시작해야 한다.
  22.  
  23.  
  24.  
  25. ## 모듈 작성 (mylib.i)
  26.  
  27. 언어간 연동을 위해 필요한 기본이 되는 단위인 모듈은 SWIG 중간 언어를 사용해서 작성한다. mylib.i 파일에 `%module mylib`이라고 작성하고, swig를 사용해 변환하면 다음과 같이 3개의 파일이 자동으로 생성된다.
  28.  
  29. * mylib_wrap.c - JNI 코드 (내부 구현)
  30.  
  31. * mylibJNI.java - Java Native를 정의한 보조 클래스 (내부 구현)
  32.  
  33. * mylib.java - Java API를 정의한 클래스. 사용자는 이 Java 클래스를 사용한다.
  34.  
  35.  
  36.  
  37. ## common directive
  38.  
  39.  
  40.  
  41. * `%inline %{ C_CODES %}` mylib.i 파일과, mylib_wrap.c 파일에 동시에 해당 코드를 작성한 것과 같은 효과를 낸다. `%{ C_CODES %}` 는 mylib_wrap.c 파일에만 작성한 효과를 내므로, `%inline` 이 더 강력하다.
  42.  
  43. * `%ignore SYMBOL_NAME` 해당 심볼을 완전히 무시한다. `ignore`는 해당 심볼이 나타나기 전에 선언되어야 한다. 이미 해당 심볼을 파싱하고 난 다음에는 의미가 없다.
  44.  
  45. * `extend STRUCT_OR_CLASS_NAME { JAVA_CODES };` 해당 이름을 갖는 구조체나 클래스에 추가 메소드를 삽입한다. `struct Foo`를 대상으로 코드를 추가한 뒤, 생성된 Foo.java 파일을 열어보면 추가된 코드를 확인할 수 있다.
  46.  
  47.  
  48.  
  49. ## typemap directive
  50.  
  51.  
  52.  
  53. 기본형(Primitive Types)를 제외한 사용자 정의 타입들은 SWIG에서 정의한 것이 없다. 따라서 해당 타입들을 적절하게 사용하려면 직접 SWIG의 `typemap` 기능을 사용해서 해당 타입을 어떻게 다룰 지를 정해줘야 한다.
  54.  
  55. _
  56.  
  57. `typemap`을 사용하면 해당 타입에 대한 완전한 제어를 할 수 있게 되지만 다음과 같은 위험이 있다.
  58.  
  59. * 개발자가 직접 C/C++ 연동 코드 일부를 작성해야 한다.
  60.  
  61. * 개발자가 직접 연동 코드를 작성하기 때문에, JNI를 깊게 알아야 한다.
  62.  
  63. * 조금이라도 잘못 작성하면 SWIG 전체 연동 코드를 망칠 수 있다.
  64.  
  65.  
  66.  
  67.  
  68. 간단하게 정리한 `typemap` 디렉티브의 종류 (더 많지만 생략)
  69.  
  70. * `%typemap(jstype) PROTOTYPE "TYPENAME";` mylib.java에 나타날 타입
  71.  
  72. * `%typemap(jtype) PROTOTYPE "TYPENAME";` mylibJNI.java에 나타날 타입
  73.  
  74. * `%typemap(jni) PROTOTYPE "TYPENAME";` mylib_wrap.c에 나타날 타입
  75.  
  76. * `%typemap(in) (PROTOTYPE) { JNICODE };` mylib_wrap.c에 매개변수로 넘어온 jtype을 C 타입으로 변환하는 코드를 직접 작성하는데 사용
  77.  
  78. * `%typemap(argout) PROTOTYPE %{ JNICODE %};` mylib_wrap.c에 매개변수로 넘어온 jtype과 관련된 동작이 모두 끝난 부분에 추가될 C 코드
  79.  
  80. * `%fragment("FRAGMENT_NAME", "header") { C_CODES }` typemap에 반복적으로 사용될 코드를 묶고, 이름을 둬서 나중에 typemap을 적용할 때 참조할 수 있게 한다. `typemap(in), typemap(varin)` 처럼 같은 목적의 C 코드가 반복될 것으로 예상되는 부분에 활용.
  81.  
  82. * `%apply TARGET_TYPE { CURRENT_TYPE }` CURRENT_TYPE으로 선언된 코드를 마치 TARGET_TYPE으로 선언한 것과 같이 취급한다.
  83.  
  84.  
  85.  
  86. ### typemap(in) TYPE
  87.  
  88.  
  89.  
  90. `%typemap(in)`은 해당 타입을 C 타입으로 변환하는 방법을 지시하는데 사용된다.
  91.  
  92. _
  93.  
  94. 먼저 가장 간단한 예제는 다음과 같다.
  95.  
  96. ```
  97.  
  98. %typemap(in) int {
  99.  
  100. $1 = $input;
  101.  
  102. printf("Received an integer : %d\n", $1);
  103.  
  104. }
  105.  
  106. ```
  107.  
  108. int 타입이 매개변수로 들어왔을 때, mylib_wrap.c에서 처리하는 방법을 지시했다. 코드가 뭘 하는지는 명확하므로 설명하지 않고, 새로 등장한 키워드를 정리한다.
  109.  
  110. * `$1` 매개변수는 jint로 넘어왔을 테니, 이를 담을 c타입을 선언한다
  111.  
  112. * `$input` 매개변수를 의미한다
  113.  
  114. _
  115.  
  116. ## SWIG 헤더
  117. SWIG는 다양한 헤더를 통해, 개발자가 필요로 할 것으로 에상하는 기능을 제공한다. C and JAVA 상황에서 유용한 헤더는 다음과 같다.
  118. * `%include <stdint.i>` C의 stdint와 같은 효과를 낸다.
  119. * `%include <typemaps.i>` 기초 자료형에 대해 INPUT, OUTPUT, INOUT 타입맵을 제공한다. 포인터 매개변수 형태로 값을 반환하는 라이브러리와 연동할 때 매우 유용하다
  120. * `%include <various.i>` char**, BYTE array타입을 지원한다
  121.  
  122. ## 각 파일에 소스코드를 직접 추가하는 방법
  123. mylib.java
  124. ```
  125. %pragma(java) modulecode=%{
  126. /* comments on mylib.java */
  127. %}
  128. ```
  129.  
  130. mylibJNI.java
  131. ```
  132. %pragma(java) jniclasscode=%{
  133. /* comments on mylibJNI.java */
  134. %}
  135. ```
  136. mylib_wrap.c
  137. ```
  138. %{
  139. /* cmments on mylib_wrap.c ! */
  140. %}
  141. ```
  142.  
  143. GENERATED-TYPE.java
  144. ```
  145. %typemap(javacode) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [ANY] %{
  146. public void foo() {
  147. System.out.println("$javaclassname");
  148. }
  149. %}
  150. ```
Add Comment
Please, Sign In to add comment