.NET C#에서 자바 JNI 통신하기

 cocos2d-x에서 안드로이드와 네이티브 C++ JNI 통신을 해봤었고 유니티3D 안드로이드 플러그인과도 JNI 통신을 해봤습니다. 이번에는 닷넷 프레임워크 C#과 자바 JNI 통신 해야할 이슈가 생겨서 관련해서 R&D 해본것을 정리해봅니다.


 먼저 자바와 C#간 JNI 처리를 도와주는 모듈들이 위와 같이 몇개 있더군요. 이중에서 제일 위에 있는 것을 가지고 C# 콘솔 어플리케이션에 연동하는 것을 정리합니다.

 링크를 클릭하시면 코드프로젝트로 이동하게 되는데 가입하지 않았다면 가입을 하신 후 해당 소스코드를 다운로드 합니다.

 JNI.dll 레퍼런스를 얻기위해 적당한 곳에 압축 해제 후 프로젝트를 열어 빌드를 해줍니다.

 JNI\Component\bin\Debug 에 JNI.dll이 생성되었습니다. 잠시 후 이것을 C# 콘솔 프로젝트에 추가해야 합니다.

 C# 콘솔 프로젝트를 간단히 만드신 후 References 마우스 우클릭 후 Add Reference 를 선택합니다. 위와 같은 다이얼로그 창이 뜨면 Browse를 눌러 좀전에 빌드한 JNI 파일을 지정해줍니다.

 OK를 눌러 적용합니다.

 마지막으로 다운로드한 소스의 JNI 폴더에 있는 HelloWorld.class 파일을 작업중인 콘솔 프로젝트의 bin\debug에 복사해줍니다. 이 파일은 같이 있는 HelloWorld.java를 컴파일 한 듯하네요. 위 그림에서 오른쪽이 원본 소스고 왼쪽이 작업중인 C# 콘솔 프로젝트입니다.

 이것으로 준비작업은 되었구요, 이제 코드 작업입니다. 사실 소스 내용은 샘플 소스와 크게 다르지 않습니다. 윈폼 기반이냐 콘솔 기반이냐 차이죠.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// JNI 사용을 위해 추가
using JNI;
// Path
using System.IO;
// Assembly
using System.Reflection;

namespace jnicsharpConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // 자바VM 로그 옵션 파라메터 딕셔너리
            Dictionary<string, string> jvmParameters = new Dictionary<string, string>();
            JavaNativeInterface Java;
            Java = new JavaNativeInterface();

            // class 패스를 현재 작업 위치로 설정하기 위한 파라메터
            string strkey = "-Djava.class.path";
            string strValue = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            jvmParameters.Add(strkey, strValue);

            Java.LoadVM(jvmParameters, false);
            // HelloWorld 객체 생성
            Java.InstantiateJavaObject("HelloWorld");

            // 자바 버전 출력
            System.Console.WriteLine(Java.JavaVersion());

            // JNI에 넘겨줄 파라메터 리스트
            List<object> jniParam = new List<object>();

            // String 인자 하나를 받는 리턴타입 void인 함수 호출
            jniParam.Add("WestWoodForever");
            Java.CallVoidMethod("HelloWorldProcedure", "(Ljava/lang/String;)V", jniParam);

            // 두 수의 합을 리턴하는 함수 호출
            jniParam.Clear();
            jniParam.Add(2);
            jniParam.Add(5);
            jniParam.Add("WestWoodForever");
            string returnJNI = Java.CallMethod<int>("AddTwoNumbers", "(IILjava/lang/String;)I", jniParam).ToString();
            System.Console.WriteLine(returnJNI);
         
            Java.Dispose();
        }
    }
}

 설명은 주석으로 대체하고 결과 화면을 보시면,

 HelloWorld 객체가 만들어졌고 자바 버전이 출력되었습니다. 제 닉네임을 HelloWorldProcedure 함수에 넘겨서 팝업 창이 뜬 상태고 확인을 누르면

 두 수의 합을 구해 리턴하는 AddTwoNumbers가 호출됩니다.

 최종 콘솔은 이렇구요. 자바 소스를 보시면 아래와 같습니다.

import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class HelloWorld extends JFrame {

    public static void main(String args[])
    {
     HelloWorld a = new HelloWorld();
     int[] myArray = { 4, 7, 5, 9, 2, 0, 1 };

     a.AddArray(myArray);
    }

    HelloWorld() {}
    {
      JLabel jlbHelloWorld = new JLabel("Hello World");
      add(jlbHelloWorld);
      this.setSize(100, 100);
      setVisible(true);
    }

    public void HelloWorldProcedure(String str)
    {
      JOptionPane.showMessageDialog(this, "Hello World by : ".concat(str), "Hello", JOptionPane.INFORMATION_MESSAGE, null );      
    }
     
    public int AddTwoNumbers(int FirstValue, int SecondValue, String str)
    {    
      JOptionPane.showMessageDialog(this, "Hello ".concat(str) + "\n" +
                                 "AddTwoNumbers with the parameters : " + Integer.toString( FirstValue ) +
                                 " and "  + Integer.toString( SecondValue ) + " will return " +
                                 Integer.toString( FirstValue + SecondValue ),
                                 "Hello", JOptionPane.INFORMATION_MESSAGE, null );
      return  FirstValue + SecondValue;
    }

    public int AddTwoNumbersFromArray(int[] val, String str)
    {    
      JOptionPane.showMessageDialog(this, "Hello ".concat(str) + "\n" +
                                 "AddTwoNumbers with the parameters : " + Integer.toString( val[0] ) +
                                 " and "  + Integer.toString( val[1] ) + " will return " +
                                 Integer.toString( val[0] + val[1] ),
                                 "Hello", JOptionPane.INFORMATION_MESSAGE, null );
      return  val[0] + val[1];
    }

    public void AddArray(int[] val)
    {    
      JOptionPane.showMessageDialog(this, "Hello simon" + "\n" +
                                 "AddTwoNumbers with the parameters : " + Integer.toString( val[0] ) +
                                 " and "  + Integer.toString( val[1] ) + " will return " +
                                 Integer.toString( val[0] + val[1] ),
                                 "Hello", JOptionPane.INFORMATION_MESSAGE, null );
    }

}

 다음 포스팅은 이것을 기반으로 WCF 웹서버에서 구글 인앱 V3 영수증 인증 처리하는 것을 정리할 예정입니다.

이 블로그의 인기 게시물

CMake Windows에 설치하기

Unity3D 안드로이드 Keystore 생성하기

Unity3D iOS Plugin 만들어 연동하기