2011-02-11 8 views
2

JNI를 사용하여 Objective-C에서 Java 함수를 호출하는 방법을 파악하는 데 정말 어려움을 겪고 있습니다.JNI를 사용하여 Cocoa에서 Java 클래스 함수 호출

나는 Java에 관해서는 아무 것도 모르지만 Obj-C에 대해서는 매우 익숙하다는 말로 시작해야합니다. 내 애플 리케이션 번들에서 호출 해야하는 단일 메서드를 사용하여 단일 Java 클래스가 있습니다. jar 파일은 번들의 Resources 폴더 안에 있고 NSJavaRootContent/Resources, NSJavaNeeded은 선택되어 있고 NSJavaPath에는 2 개의 jar 파일 (주된 하나의 의존성)의 이름이 들어 있습니다.

JNI_CreateJavaVM에 대한 호출을 사용하여 VM을 실행 한 다음 NSClassFromString을 사용하여 클래스를 찾으려고 시도했지만 잘못된 검색이 내 검색에서 발견 된 유일한 방법입니다. 이 메서드는 사용되지 않는 Java 브리지를 사용할 때 올바른 것으로 생각되지만 JNI를 사용하는 예제 나 참조를 찾을 수 없습니다.

내 자바 클래스는 다음과 같습니다

package foo; 

public class bar { 

    public function dostuff() { 

    } 

} 

나는 응용 프로그램 흐름의 한 부분으로 한 번 dostuff()를 호출해야합니다. 누구든지 어떻게 할 수있는 아이디어가 있습니까?

감사합니다, J JavaBridge가 사용되지 않습니다 때문에

답변

12

, 당신은 모든 JNI이 작업을 수행해야 할 것입니다. 맥 OS에, 당신은 당신의 프로젝트에 JavaVM.framework을 추가 할 것이고, 소스 파일에서, 당신이 찾고있는 헤더는 다음과 같습니다

#import <JavaVM/jni.h> 

다음 당신은의 JavaVM을 설정해야합니다.

JNI_CreateJavaVM(JavaVM **pJVM, void **pJNIEnv, void *args); 

다음은 당신이 얻을 싶을 것이다 :이 기능을 사용하면 JVM을 만들 때 사용하는 것입니다 이것은 클래스 패스 및 기타 요구 사항에 따라, 사소 할 수 있지만, 올바른 방향으로 가고있는 것입니다 수업 foo.bar에 대한 참조. 이것은 JNI_CreateJavaVM에서 전달 된 pJNIEnv를 사용하여 수행 할 수 있습니다. 전화 하시려면 다음 번호로 전화하십시오.

jclass myClass = JNIEnv->FindClass(JNIEnv, "foo/bar"); // Note the slashes replacing the dots... 

모든 것이 올바르게 설정되었다고 가정하면 수업에 대한 참조가 다시 전달됩니다. foo.bar가 기본 매개 변수가없는 생성자가 잠시 동안 가정하면, 다음과 같이 그것의 인스턴스를 얻을 수 있습니다 :

jobject myFooBar = JNIEnv->NewObject(JNIEnv, myClass); 

지금 당신은 당신의 doStuff 방법의 methodID를 얻을 필요가있다. 이렇게하려면, 당신은해야합니다 그것은 같은 당신은 javap 호출하여 얻을 수있는 방법 서명,이다 :

이 같은 출력을 생성한다
% javap -s foo.bar 

:

Compiled from "bar.java" 
public class foo.bar extends java.lang.Object{ 
public foo.bar(); 
    Signature:()V 
public void doStuff(); 
    Signature:()V 
} 

그런 다음에 그것을 사용할 수 있습니다 methodID를 가져와야합니다.이 메소드를 호출해야합니다. 그래서 같이 :

JNIEnv->CallVoidMethod(JNIEnv, myFooBar, mid); 

및 방법은 전화를받을해야 모든 일이 잘 갈 가정

jmethodID mid = JNIEnv->GetMethodID(JNIEnv, myClass, "doStuff", "()V"); 

, 당신은 방법과 같이 호출 할 수 있습니다.이 단계가 끝나면 예외가 있는지 확인하기 위해 VM을 확인하려고합니다. 당신은 예외가이 작업을 수행하여 발생했는지 확인할 수 있습니다 :

if (JNIEnv->ExceptionCheck(JNIEnv)) 
{ 
    // Handle the exception... 
} 

당신이 실제 throw 가능 객체를 원하는 경우

, 당신은 위해 ExceptionOccured JNI 방법을 사용하여 얻을 수 있습니다.

그렇기 때문에 JNI를 사용하여 Cocoa에서 Java 메소드를 호출하는 방법이 가장 많습니다. JNI 문서, 글로벌 및 로컬 참조의 차이점을 이해하는 부분을 읽어 보는 것이 좋습니다. (즉, 코코아 측 참조가 생성 된 범위 밖에서 호출 될 수있을 정도로 길다는 것을 의미합니다.) 실제로 많은 일반적인 실수와 함정에 대해서는 전체 장을 제공합니다. 행운

http://java.sun.com/docs/books/jni/

좋은!

+0

감사합니다. 그게 정확히 시행 착오를 통해 끝난 것입니다. 바라기를이 명확한 묘사는 동일한 상황에서 찔린 누군가 다른 사람을 도울 것이다! – JWood

+0

정말 고마워요. 이것은 어디에서도 찾을 수 없었기 때문에이 멋진 리소스입니다. –

관련 문제