JNI允许运行在虚拟机的Java程序能够与其它语言(例如C和C++)编写的程序或者类库进行相互间的调用。我想在C/C++中调用Java方法,是用JDK1.4.2,以及Visual C++ 6。按照步骤一步步都做好了,其中有一步是在C里面初始化java虚拟机,就是需要jvm.dll,照介绍的路径jvm.dll 应该是
[JDK目录]\bin\classic里面。可是,\bin下根本就没有\classic!所以也就没有jvm.dll。然后搜索发现,在[JDK目录]\jre\bin\下有两个目录:……\client和……\server,他们下面分别有一个jvm.dll,就把它们分别试了一下可惜都不行,教教我该怎么做呀!!
[JDK目录]\bin\classic里面。可是,\bin下根本就没有\classic!所以也就没有jvm.dll。然后搜索发现,在[JDK目录]\jre\bin\下有两个目录:……\client和……\server,他们下面分别有一个jvm.dll,就把它们分别试了一下可惜都不行,教教我该怎么做呀!!
我从没碰到过这个问题
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
取得CurrentVersion的值,假设是1.4在到HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.4下
取得RuntimeLib的值,就是jvm.dll的路径。
后来改成PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin\client;C:\Inprise\vbroker\bin;…………
因为%JAVA_HOME%\jre\bin\client下面有jvm.dll,
可是都不行刚才照“实在无聊”的方法改成PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin\client\jvm.dll;C:\Inprise\vbroker\bin;…………结果,刚才的问题没有了,但是屏幕上出来好多这样的:
[Dynamic-linking native method java.lang.StrictMath.pow ... JNI]
[Dynamic-linking native method java.lang.Float.intBitsToFloat ... JNI]
[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]
[Dynamic-linking native method java.lang.Float.floatToIntBits ... JNI]
[Dynamic-linking native method java.lang.Double.doubleToLongBits ... JNI]
[Dynamic-linking native method java.lang.Object.registerNatives ... JNI]
[Registering JNI native method java.lang.Object.hashCode]
[Registering JNI native method java.lang.Object.wait]
…………
很多,没有运行出来结果调用的那个Java方法本身是可以正确运行的
jvm.dll 有client,也有server,
显示为classic是运行的好像比较早的版本,如你用java运行一个程序就可以加上一个classic参数
一般只需要用加载jre/bin/clinet/jvm.dll。编译的时候需要使用到 lib/jvm.lib 这个库。否则可能会出错。至于运行时,把你调用上层的 .class ,或者.jar放到jre/lib/ext下就可以了。
#include <stdio.h>
#include <stdlib.h>void main(){
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args; int res; vm_args.version = JNI_VERSION_1_4; //vm_args.nOptions = 4;
//JavaVMOption options[4];
//这里,有的介绍设的值是2,有3也有4,下面用的是3 JavaVMOption options[3];
vm_args.nOptions = 3;
options[0].optionString = "-verbose:jni";
options[1].optionString = "-Djava.class.path=.";
options[2].optionString = "-Djava.compiler=NONE";
//options[2].optionString = "-Djava.library.path=.";
vm_args.ignoreUnrecognized = JNI_TRUE;
vm_args.options = options; //jint result = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args); if(res<0){
fprintf(stderr,"can't creat Java VM");
exit(1);
}
jclass mainClass = env->FindClass("NativeTest");
jmethodID method = env->GetStaticMethodID(mainClass,"main","([Ljava/lang/String;)V");
jclass stringClass = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0,stringClass,NULL);
env->CallStaticVoidMethod(mainClass,method,args);
jvm->DestroyJavaVM();
fprintf(stdout,"Java VM destory");
}
1.Include files的路径,包括
D:\j2sdk\include\win32
D:\j2sdk\include
还有C程序和Java方法所在的目录(它们在同一个目录下)
2.Library files路径,包括
D:\j2sdk\lib
public static void main(String[] args){
NativeTest nt=new NativeTest();
}
public NativeTest(){
System.out.println("Hello,Maggie!!!");
}
}这个没有问题吧
#include <crtdbg.h>
#define JNI_VERSION JNI_VERSION_1_2
typedef JNIIMPORT jint
(JNICALL *P_CreateJavaVM) (JavaVM **pvm, void **penv, void *args);
BOOL CreateJavaVM(JavaVM** pjvm,JNIEnv** penv,int optionCount,const char* options[])
{
HKEY hKey;
LONG r = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\JavaSoft\\Java Runtime Environment",
NULL,KEY_READ,&hKey);
if (r != ERROR_SUCCESS)
{
return FALSE;
}
char jvmPath[512];
DWORD cbr;
DWORD type;
cbr = sizeof(jvmPath);
r = ::RegQueryValueEx(hKey,"CurrentVersion",NULL,&type,(LPBYTE)jvmPath,&cbr);
if (r != ERROR_SUCCESS)
{
::RegCloseKey(hKey);
return FALSE;
}
jvmPath[cbr] = NULL;
HKEY hKey2;
r = ::RegOpenKeyEx(hKey,jvmPath,NULL,KEY_READ,&hKey2);
if (r != ERROR_SUCCESS)
{
::RegCloseKey(hKey);
return FALSE;
}
cbr = sizeof(jvmPath);
r = ::RegQueryValueEx(hKey2,"RuntimeLib",NULL,&type,(LPBYTE)jvmPath,&cbr);
::RegCloseKey(hKey);
::RegCloseKey(hKey2);
if (r != ERROR_SUCCESS)
return FALSE;
HMODULE h = ::LoadLibrary(jvmPath);
if (h == NULL)
return FALSE;
P_CreateJavaVM procJvm = (P_CreateJavaVM)::GetProcAddress(h,"JNI_CreateJavaVM");
_ASSERT(procJvm != NULL);
if (procJvm == NULL)
return FALSE;
JavaVM* jvm=NULL;
JNIEnv* env=NULL;
JavaVMInitArgs vm_args;
ZeroMemory(&vm_args,sizeof(JavaVMInitArgs));
vm_args.version = JNI_VERSION;
vm_args.nOptions = optionCount;
if (optionCount > 0)
{
vm_args.options = new JavaVMOption[optionCount];
for(int i=0;i<optionCount;i++)
{
vm_args.options[i].optionString = (char*)options[i];
}
} r = procJvm(&jvm,(void**)&env,&vm_args);
if (optionCount > 0)
delete [] vm_args.options;
if (r != 0)
return FALSE;
if (pjvm != NULL)
*pjvm = jvm;
if (penv != NULL)
*penv = env;
return TRUE;
}
必须是2以后的,应该最好用4,因为你的是1.4.2LoadLibrary("D:\\jsdk\\jre\\bin\\jvm.dll");设置相应的你需要加载的dll即可但必须注意要把 jvm.lib 添加到工程配置中(你的配置中已经加了)
或者在代码中使用
#param commment(lib,"相应路径\\jvm.lib")回复人: taolei(实在无聊) ( ) 信誉:100
按照他说的就可以了,不过我觉得没有必要去查注册表,使用相对路径是最好了
:)
我找到我的问题了,调用的JAVA方法的路径问题!