.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 영수증 인증 처리하는 것을 정리할 예정입니다.
- Using the Java Native Interface in C#
- jni4net
- jnicsharp
- How to wrap a C# library for use in Java
- IKVM.NET
- j-Interop
먼저 자바와 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();
}
}
}
설명은 주석으로 대체하고 결과 화면을 보시면,
두 수의 합을 구해 리턴하는 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 영수증 인증 처리하는 것을 정리할 예정입니다.
댓글
댓글 쓰기