C++ 애플리케이션에서 Java 메서드에 액세스하는 방법
간단한 질문입니다.c/c++에서 자바 함수를 호출할 수 있습니까?
네, 할 수 있지만 약간 복잡하며 반사형/비형 안전한 방식으로 작동합니다(예: C 버전보다 조금 더 깨끗한 C++ API 사용).이 경우 C 코드 내에서 Java VM의 인스턴스를 생성합니다.Java에서 처음 네이티브 코드를 호출하는 경우 VM 인스턴스를 구성할 필요가 없습니다.
#include<jni.h>
#include<stdio.h>
int main(int argc, char** argv) {
JavaVM *vm;
JNIEnv *env;
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = 1;
// Construct a VM
jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
// Construct a String
jstring jstr = env->NewStringUTF("Hello World");
// First get the class that contains the method you need to call
jclass clazz = env->FindClass("java/lang/String");
// Get the method that you want to call
jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase",
"()Ljava/lang/String;");
// Call the method on the object
jobject result = env->CallObjectMethod(jstr, to_lower);
// Get a C-style string
const char* str = env->GetStringUTFChars((jstring) result, NULL);
printf("%s\n", str);
// Clean up
env->ReleaseStringUTFChars(jstr, str);
// Shutdown the VM.
vm->DestroyJavaVM();
}
Ubuntu에서 컴파일하기
g++ -I/usr/lib/jvm/java-6-sun/include \
-I/usr/lib/jvm/java-6-sun/include/linux \
-L/usr/lib/jvm/java-6-sun/jre/lib/i386/server/ -ljvm jnitest.cc
참고: 올바른 오류 처리를 구현하려면 이러한 각 방법의 반환 코드를 확인해야 합니다(편의상 무시했습니다).예.
str = env->GetStringUTFChars(jstr, NULL);
if (str == NULL) {
return; /* out of memory */
}
네, 하지만 JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html 를 통해 해야 합니다.
여러 가지 방법이 있습니다.여기 몇 가지 아이디어가 있습니다.또한 상용 Java-COM 브리지를 통해 C++에서 Java(Windows를 사용하는 경우)로 COM 통신을 수행할 수 있습니다.CNI도 살펴봐야 합니다.
호출 API를 살펴봅니다.이렇게 하면 기본 애플리케이션 내에서 JVM을 로드하고 시작한 다음 애플리케이션에서 메서드를 호출할 수 있습니다.
간략하게(연결된 문서에서)
/* load and initialize a Java VM, return a JNI interface
* pointer in env */
JNI_CreateJavaVM(&jvm, &env, &vm_args);
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, 100);
다음 기능을 사용하여 VM을 생성할 수 있습니다.
JNIEnv* create_vm(JavaVM ** jvm)
{
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[2];
options[0].optionString = "-Djava.class.path=.";
options[1].optionString = "-DXcheck:jni:pedantic";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 2;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE; // remove unrecognized options
int ret = JNI_CreateJavaVM(jvm, (void**) &env, &vm_args);
if (ret < 0) printf("\n<<<<< Unable to Launch JVM >>>>>\n");
return env;
}
유명한 헬로 월드 프로그램을 컴파일합니다.다음 함수는 HelloWorld 프로그램의 메인 메서드를 호출하려고 합니다.
int main(int argc, char* argv[])
{
JNIEnv* env;
JavaVM* jvm;
env = create_vm(&jvm);
if (env == NULL) return 1;
jclass myClass = NULL;
jmethodID main = NULL;
myClass = env->FindClass("HelloWorld");
if (myClass != NULL)
main = env->GetStaticMethodID(myClass, "main", "([Ljava/lang/String;)V");
else
printf("Unable to find the requested class\n");
if (main != NULL)
{
env->CallStaticVoidMethod( myClass, main, " ");
}else printf("main method not found") ;
jvm->DestroyJavaVM();
return 0;
}
이제 create_vm 함수와 main 함수를 단일 cpp 파일에 넣고 jni.h를 포함하여 컴파일합니다.저는 윈도우에서 MinGW를 사용했습니다.
g++ -D_JNI_IMPLEMENTATION_ -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" hello.cpp -L"C:\Program Files\Java\jre6\bin\client" -ljvm -o hello.exe
이제 생성된 exe를 실행하면 오류가 발생합니다. jvm.dll을 찾을 수 없습니다. PutC:\Program Files\Java\jre6\bin\client사용자의 PATH 환경 변수에 있습니다.이제 exe 파일을 실행할 수 있습니다.
참고: jvm.dll 파일을 대체하지 마십시오.
예, C++ 또는 C에서 Java 함수를 호출할 수 있지만 COM 또는 CORBA(또는 제가 모르는 다른 타사 도구)와 같은 것을 사용하지 않는 한 JNI의 맥락에서 이 작업을 수행해야 합니다.
네이티브 코드에서 Java 메서드를 호출하는 전체 절차는 Sun의 JNI 가이드 pdf에서 "호출 방법"이라고 하는 섹션 4.2의 4장에 설명되어 있으며, 여기에서 찾을 수 있습니다.
위의 예제를 코딩한 후에는 프로젝트에서 몇 가지 구성을 수행해야 합니다.
Visual Studio에서 jvm.lib를 프로젝트에 연결하는 단계:
- 프로젝트 -> 속성을 마우스 오른쪽 버튼으로 클릭합니다.
- 속성 대화 상자에서 링커->입력->추가 종속성 영역 아래에 jvm.lib를 추가합니다.
- 마지막으로 링커->일반->추가 라이브러리 디렉터리 아래에 jvm.lib 경로(예: "C:\Program Files\Java\jdk1.7.0_60\lib")를 씁니다.
이러한 단계를 거치면 프로젝트가 jvm에 연결되어 잘 작동할 수 있습니다.
언급URL : https://stackoverflow.com/questions/992836/how-to-access-the-java-method-in-a-c-application
'programing' 카테고리의 다른 글
| 이벤트 이미터와 이벤트 이미터의 차이점은 무엇입니까? (0) | 2023.06.13 |
|---|---|
| rbenv install 명령이 누락되었습니다. (0) | 2023.06.13 |
| 빈 테이블의 MAX()를 NULL이 아닌 0으로 처리하는 방법 (0) | 2023.06.08 |
| 개체가 유형이 아닌지 확인(!= "IS"에 해당) - C# (0) | 2023.06.08 |
| 스트링 배열을 numpy로 플로트 배열로 변환하는 방법은 무엇입니까? (0) | 2023.06.08 |