只是一個簡單的問題: 是否可以從c/C++調用java函數?如何訪問C++應用程序中的Java方法
回答
是的,你可以,但它有點複雜,並且以反射/非類型安全的方式工作(例子使用C++ api,它比C版本更清潔)。在這種情況下,它會在C代碼中創建Java VM的實例。如果你的母語稱作是首先被從Java叫那麼就沒有必要建立一個虛擬機實例
#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
是的,你可以調用從C Java函數++或C,但除非你使用像COM或CORBA(或其他第三方工具,我可能不知道的),你會必須在JNI的背景下做到這一點。
從本機代碼調用Java方法的整個過程在Sun的JNI指南pdf中的第4.2節中稱爲「調用方法」的第4章中描述,您可以在其中找到here。
看一下invocation 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);
以下功能允許您創建虛擬機。
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;
}
編譯着名的Hello World程序。以下函數嘗試調用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
Exection 現在,如果你運行exe文件創建,你會得到一個錯誤。 jvm.dll not found。 將C:\Program Files\Java\jre6\bin\client
放入您的PATH環境變量中。現在你可以運行這個exe文件 。
注意:不要取代jvm.dll文件。
編碼上面的例子後,你需要對你的項目做一些配置。
步驟來jvm.lib在Visual Studio中鏈接到您的項目:
- 右鍵單擊項目 - >屬性。
- 在屬性對話框中,在鏈接器 - >輸入 - >附加依賴關係區域添加jvm.lib。
- 最後寫jvm.lib路徑(如 「C:\ Program Files文件\的Java \ jdk1.7.0_60 \ LIB」)下 連接器 - >常規 - > AdditionalLibraryDirectories
完成這些步驟之後,你的項目能鏈接到jvm並且運行良好。
- 1. 從C#程序的DLL訪問方法
- 2. 無法訪問Web應用程序中新增的WCF方法
- 3. C#webservice和Android應用程序:如何防止非法訪問
- 4. 如何訪問java中的應用程序軟件
- 5. 如何從主應用程序訪問Rails引擎方法?
- 6. 如何從基礎應用程序訪問方法?
- 7. 如何限制跨應用程序訪問方法?
- 8. 如何訪問命令行應用程序的包中的C
- 9. 如何訪問c#WPF應用程序中的commandbindings?
- 10. 無法訪問應用程序引擎中的文件java
- 11. 如何在java方法中訪問'this'?
- 12. 如何在Obj-C應用程序中訪問和使用dylib?
- 13. 如何在Android應用程序中使用WebView訪問我的Web應用程序的JavaScript方法?
- 14. 如何在maven web應用程序中訪問目錄(java)
- 15. 如何在Java應用程序中訪問Google Maps API?
- 16. 如何從iPad上的應用程序訪問第三方應用程序?
- 17. 在Java程序中調用C#方法
- 18. rails:我如何訪問我的應用程序控制器中的方法?
- 19. ColdSpring的子應用程序無法訪問軟件包方法
- 20. 訪問來自Java應用程序
- 21. 通過Java應用程序訪問SharePoint
- 22. 訪問到Java應用程序從PHP
- 23. Web應用程序URL訪問java
- 24. 通過Java應用程序訪問Facebook
- 25. 從PHP訪問java應用程序
- 26. 如何在jquery方法中訪問ViewModel屬性的asp.net mvc2應用程序
- 27. 如何從控制檯應用程序訪問Web API中的不同方法?
- 28. 如何從Java應用程序訪問我的Gmail郵件?
- 29. 如何從其他方法訪問java中的方法?
- 30. 如何從C#中的線程訪問非靜態方法
我見過JNI用來從Java調用C++。不知道它以另一種方式工作。 – Kieveli 2009-06-14 13:35:04
奇怪的是,我一直認爲它更常用於提供從Java訪問C++庫,但它有兩種方式。例如, – 2009-06-14 13:38:51