Calling Java Method From C
I again did the whole things from strach but failed again.
1. I wrote the C program
#include <jni.h>
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif
int main() {
JavaVMOption options[1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
jint square;
jboolean not;
options[0].optionString = "-Djava.class.path=.";
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
}
2. I tried compiling the above. But I get
Error: Unresolved external 'JNI_CreateJavaVM' referenced from C:\JNITEST\JNIEXAMPLE.OBJ
i. I am using BCC compiler
ii. bcc32.cfg file contains
-I"C:\BCC55\Include"
-I"C:\Program Files\Java\jdk1.5.0_02\include\win32"
-I"C:\Program Files\Java\jdk1.5.0_02\include"
-L"C:\BCC55\Lib"
-L"c:\Program Files\Java\jdk1.5.0_02\lib"
iii. Command Line Argument being given for compiling is
C:\JniTest>bcc32 -IC:\Program/Files\Java\jdk1.5.0_02\include JniExample.c -Lc:\Program/Files\Java\jdk1.5.0_02\lib\jvm.lib
-IC:\Program/Files\Java\jdk1.5.0_02\include: Contains Jni.h
iv. Env Variable path has the following
C:\Program Files\Java\jdk1.5.0_02\bin\;
C:\bcc55\Bin\;
C:\Program Files\Java\jdk1.5.0_02\jre\bin\client\;
C:\Program Files\Java\jdk1.5.0_02\jre\bin
WHERE AM I GOING WRONG ...
# 4
When I give this
cl -IC:\Program/Files\Java\jdk1.5.0_05\include -MD CallingJavaCodeFromC.c -link C:\Program/Files\Java\jdk1.5.0_05\lib\jvm.lib
--
C:\MyWork>cl -IC:\Program/Files\Java\jdk1.5.0_05\include -MD CallingJavaCodeFrom
C.c -link C:\Program/Files\Java\jdk1.5.0_05\lib\jvm.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
CallingJavaCodeFromC.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
/out:CallingJavaCodeFromC.exe
C:\Program/Files\Java\jdk1.5.0_05\lib\jvm.lib
CallingJavaCodeFromC.obj
LINK : fatal error LNK1181: cannot open input file 'C:\Program/Files\Java\jdk1.5
.0_05\lib\jvm.lib'
# 7
Please use the following code :Use the loadLibrary function to load the jvm.dll instead of linking jvm.lib
#define JRE_KEY "SOFTWARE\\JavaSoft\\Java Runtime Environment"
#define CURVER_STR"CurrentVersion"
#define RUNLIB_STR"RuntimeLib"
int readStringFromRegistry(HKEY hkey,const char * name,char * buf,DWORD bufsize)
{
DWORD type = REG_DWORD;
DWORD size;
if ((RegQueryValueEx(hkey, name, NULL, &type, NULL, &size) == ERROR_SUCCESS)
&& (type == REG_SZ)
&& (size < bufsize))
{
if (RegQueryValueEx(hkey, name, NULL, NULL,(LPBYTE)buf, &size) == ERROR_SUCCESS)
return 0;
}
return -1;
}
int readJVMPathFromReagistry(char* buf,int bufsize)
{
HKEY hkey,subkey;
char version[MAX_PATH];
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,JRE_KEY, 0,KEY_ALL_ACCESS,&hkey)!=ERROR_SUCCESS)
{
return -1;
}
if (readStringFromRegistry(hkey, CURVER_STR, version, sizeof(version)) != 0) {
RegCloseKey(hkey);
return -2;
}
if (RegOpenKeyEx(hkey,version, 0, KEY_READ, &subkey) != ERROR_SUCCESS) {
RegCloseKey(hkey);
return -3;
}
if (readStringFromRegistry(subkey, RUNLIB_STR,buf,bufsize) != 0) {
RegCloseKey(subkey);
RegCloseKey(hkey);
return -4;
}
RegCloseKey(subkey);
RegCloseKey(hkey);
return 0;
}
JNIEnv* CreateVm()
{
char jvmPath[MAX_PATH];
JavaVM *vm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint res;
JNIEnv *env;
if (readJVMPathFromReagistry(jvmPath, sizeof(jvmPath)) != 0)
return NULL;
//load the JVM DLL
HINSTANCE handle = LoadLibrary(jvmPath);
if( handle == 0)
{
printf("Failed to load jvm dll %s\n", jvmPath);
return NULL;
}
//get the function pointer to JNI_CreateJVM
createJVM = (CreateJavaVM)GetProcAddress(handle, "JNI_CreateJavaVM");
if (createJVM == NULL)
{
printf("Unable to find JNI_CreateJavaVM\n");
return NULL;
}
vm_args.version = JNI_VERSION_1_4;//JVM version
vm_args.nOptions = g_ivmOptionCount +1;//Number of JVM Versions
options[0].optionString = CLASS_PATH;//Class Path
//Copy all your JVM Option
for (int i = 0; i < g_ivmOptionCount; i++)
{
options[i+1].optionString = g_acvmOptions;
}
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_FALSE;
res = createJVM(&vm, (void **)&env, &vm_args);
if (res < 0)
{
printf("Error creating JVM");
return NULL;
}
return env;
}