jvm c++

Status
Nicht offen für weitere Antworten.

nameac

Bekanntes Mitglied
moin,

Code:
#include "stdafx.h" 
#include "jni.h" 
#include "windows.h" 

typedef jint (WINAPI* JNI_CREATEJAVAVM)(JavaVM **pvm, void ** penv, void *args); 

int main(int argc, char* argv[]) 
{ 
   JavaVMInitArgs vm_args; 
   JavaVMOption options[10]; 
   JavaVM* jvm; 
   JNIEnv* env; 

   options[0].optionString = "-Djava.compiler=NONE"; 
   options[1].optionString = "-Djava.class.path=D:/programme/eclipse/workspace/helloworld"; 

   vm_args.version  = JNI_VERSION_1_4; 
   vm_args.nOptions = 2; 
   vm_args.options  = options; 
   vm_args.ignoreUnrecognized = false; 

   JNI_CREATEJAVAVM JNI_CreateJavaVM = 0; 

   HMODULE hLib = LoadLibrary((LPCWSTR)"E:\\c_progs\\nativ_c\\native_c\\jvm.dll"); 

   
   JNI_CreateJavaVM = (JNI_CREATEJAVAVM) GetProcAddress(hLib, "JNI_CreateJavaVM"); 

   long status  = JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args); 
   if  (status != JNI_OK) 
   { 
      printf("Failed creating JVM. Error: %d\r\n", status); 
   } 
   else 
   { 
      printf("JVM created\r\n"); 
   } 
    jclass cls = (*env).FindClass("HelloWorld");
    if (cls == 0) {
        fprintf(stderr, "Can't find Prog class\n");
    }

      
    jmethodID mid = (*env).GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
    if (mid == 0) {
        fprintf(stderr, "Can't find Prog.main\n");
    }

    (*env).CallStaticVoidMethod(cls, mid, NULL);
 	  (*jvm).DestroyJavaVM();

   return 0; 
}
compeliert fehler frei, jdoch beim ausführen der exe kommt ein fehler :
" die anweisung in 0x00000000 verweist auf speicher in 0x00000000. der vorgang read konnte nicht durchgeführt werden."

:autsch:
 

foobar

Top Contributor
" die anweisung in 0x00000000 verweist auf speicher in 0x00000000. der vorgang read konnte nicht durchgeführt werden."
Wer kennt das nicht in C/C++? *gg*

D.h. du greifst auf einen nicht allokierten Speicherbereich zu. Der Fehler könnte z.b. hier liegen:

Code:
long status  = JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);
Denn die Pointer jvm und env zeigen auf irgendeinen nicht definierten Speicherbereich, wenn die Funktion JNI_CreateJavaVM nicht selber Speiicher für diese Variablen allokiert gibts Probleme.
Du kannst dir ja mal ein paar Meldungen in der Shell ausgeben lassen, damit du weißt bis wohin er kommt.
 

nameac

Bekanntes Mitglied
jo auch bei LoadLibrary gibts bereits probleme ich bräucht einfach mal en tutorial dazu was auch funzt wieso gibts den da nicht vernünftiges zu. :x :autsch:
 

nameac

Bekanntes Mitglied
moin,
Code:
#include "stdafx.h" 
#include "jni.h"
#include "windows.h" 
#include "Winbase.h"

typedef jint (WINAPI* JNI_CREATEJAVAVM)(JavaVM **pvm, void ** penv, void *args); 

int main(int argc, char* argv[]) 
{ 
   JavaVMInitArgs vm_args; 
   JavaVMOption options[10]; 
   JavaVM* jvm; 
   JNIEnv* env; 

   options[0].optionString = "-Djava.compiler=NONE"; 
   options[1].optionString = "-Djava.class.path=D:/programme/eclipse/workspace/helloworld"; 

   vm_args.version  = JNI_VERSION_1_4; 
   vm_args.nOptions = 2; 
   vm_args.options  = options; 
   vm_args.ignoreUnrecognized = false; 

   JNI_CREATEJAVAVM JNI_CreateJavaVM = 0; 

   HMODULE hLib = LoadLibrary(_T("E:/c_progs/nativ_c/nativ_c/jvm.dll")); 
   if(hLib==NULL){
   printf("%d",GetLastError());
   }
   
   JNI_CreateJavaVM = (JNI_CREATEJAVAVM) GetProcAddress(hLib, "JNI_CreateJavaVM"); 
   if(JNI_CreateJavaVM==NULL){
   printf("%d",GetLastError());
   }

   long status  = JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args); 
   if  (status != JNI_OK) 
   { 
      printf("Failed creating JVM. Error: %d\r\n", status); 
   } 
   else 
   { 
      printf("JVM created\r\n"); 
   } 
  
   return 0; 
}

so ich habe mich mal an diese anleitung gehalten

http://forum.javacore.de/viewtopic.php?t=3879&view=previous&sid=91b0245e49c22b1c58ba0a601085e7dd

aber ich kriege immer noch den errorcode -1
 
A

Anmeldeboykottierer

Gast
Hi,
die Frage bei dir ist ja schon, an welcher Stelle der Fehler auftaucht. Unter Windows kann ich dir etwas Code zur Verfügung stellen. Ich weiß nicht genau warum die DLL bei dir in einem so merkwürdigen Verzeichnis liegt, aber da könnte eigentlich schon dein Fehler liegen. Die DLL greift wiederum auf andere Strukturen zurück, die dann relativ dazu liegen müssten.
An sich gilt, dass du ein JRE installiert haben musst (nicht nur die DLL weiter reichen!).
Unter Windows kannst du dazu einen Registry-Key auslesen, hier mal als einfacher C Code:

Code:
#include <jni.h>
#include <tchar.h>
#include <windows.h>
#include <string.h>
#include <winreg.h>
#include <stdlib.h>
#include "Jvm_Test.h"


void initVmArgs(JavaVMInitArgs *, JavaVMOption *);
jint createJavaVm(JavaVM *, JNIEnv *, TCHAR *);
int getJvmDllPath(TCHAR* path);

/**
 *  Main 
 *  Erzeugt eine neue JMV Instanz, gibt dabei den ermittelten Pfad zur DLL
 *  und den "status" beim Erzeugen aus 
 */ 
int main() {
  JavaVM *jvm = NULL;
  JNIEnv *env = NULL;
  
  TCHAR path[MAX_PATH * 2];
  jint status;
  
  if (getJvmDllPath(&path[0])) {
    _tprintf(_T("Using %s\n"), path);
    return 0;
    status = createJavaVm(jvm, env, &path[0]);
    printf("%d", (int)status);
  }
  
  else {
    _tprintf(_T("Fehler beim Laden von %s\n"), path);
  }
	
	return 0;
}
////////////////////////////////////////////////////////////////////////////////

/**
 * Erzeugt eine neue Java Virtual Maschine
 * 
 * Ermittelt dazu aus der registry den Pfad zum JRE/der entsprechenden 
 * runtimelib
 * Mit hilfe diese Bibliothek wird dann eine Instanz erzeugt 
 *  
 * @param jvm Zeiger auf die erzeugte JavaVM 
 * @param env Zeiger auf die erzeugte JNIEnv
 * @param pathToDll Pfad zur Runtimelib des verwendeten JRE       
 */ 
jint createJavaVm(JavaVM *jvm, JNIEnv *env, TCHAR* pathToDll) {
	JNI_CREATEJAVAVM jni_createJavaVm;
	
  HMODULE hLib;
  
  JavaVMInitArgs vm_args;
  JavaVMOption options[2];

  // eigene Funktion, die einfach nur die Werte setzt
	initVmArgs(&vm_args, &options[0]);

  // dynamisches linken gegen die dll
  hLib = LoadLibrary(pathToDll);
	if(hLib == NULL)
	{
		_tprintf(_T("Unable to open %s"), pathToDll);
		return ERR_LOADLIBRARY;
	}
	
	// erzeugen der Instanz mithilfe der DLL
  jni_createJavaVm = (JNI_CREATEJAVAVM) GetProcAddress(hLib, 
                                                       DLL_JNI_CREATE_JVM);	
	
	if(jni_createJavaVm == NULL) {
    _tprintf(_T("Unable to find proc address of %s in %s"), DLL_JNI_CREATE_JVM,  pathToDll);
		return ERR_JNI_CREATE_JVM;    	     
  }
	
	return (*jni_createJavaVm)(&jvm,(void**)&env,&vm_args);
}
////////////////////////////////////////////////////////////////////////////////

/**
 * Na ja, copy&paste, muss ja nichts erklärt werden
 * Ach ja, CLASSPATH liegt als Konstante in der .h Datei         
 */ 
void initVmArgs(JavaVMInitArgs *vm_args, JavaVMOption *options) {
	options[0].optionString = "-Djava.compiler=NONE";
	options[1].optionString = strcat("-Djava.class.path=", CLASSPATH);

  (*vm_args).version = JNI_VERSION_1_4;
	(*vm_args).options = options;
	(*vm_args).nOptions = 2;
	(*vm_args).ignoreUnrecognized = JNI_FALSE;  	
}
////////////////////////////////////////////////////////////////////////////////

/**
 * Ermittelt den Pfad zur Runtimelib
 * Dazu wird aus der Registry der Schlüssel 
 * HKEY_LocalMachine\Software\JavaSoft\Java Runtime Enviroment\<Version>\
 * und hier der Wert RuntimeLib ausgelesen. Seit Java 1.2 wird hier in den 
 * Sun Implentierungen (und kompatiblen) dieser Pfad abgelegt         
 */ 
int getJvmDllPath(TCHAR* path) {
  HKEY key = NULL;
  
  DWORD subkeyCount = 0;
  DWORD maxSubkeyLength = 0;
  TCHAR* subkeyName;
  HKEY subkey;
  DWORD dwData = 256;

  DWORD i;
  int found;
  long res;
  
  // öffnen des Schlüssels 
  res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH_TO_JRE, 0, KEY_READ, &key);  
  
  if (res != ERROR_SUCCESS) {
    _tprintf(_T("Unable to open key %s\n"), REG_PATH_TO_JRE);
    printf("Error Code %d", (int)res);
    return res;
  }
  
  // abfrage aller Subschlüssel
  res = RegQueryInfoKey(key, NULL, NULL, NULL, &subkeyCount, &maxSubkeyLength, 
                        NULL, NULL, NULL, NULL, NULL, NULL);
  
  if (res != ERROR_SUCCESS) {
    printf("Unable to read subkeys \n");
    printf("Error Code %d", (int)res);
    RegCloseKey(key);
    return res;
  }

  printf("%d subkeys found", (int)subkeyCount);

  // prüfen der Subschlüssl
  // Der Pfad wird aus dem ersten Subschlüssel genommen, der den Wert 
  // Runtimelib enthält 
  if (subkeyCount > 0) {
    
    // puffer 
    subkeyName = (TCHAR*)calloc(maxSubkeyLength + 1, sizeof(TCHAR));
    
    i = 0;
    found = 0;
    
    // iterieren über alle Schlüssel
    while (!found && (i < subkeyCount)) {
    res = RegEnumKey(key, i, subkeyName, maxSubkeyLength + 1);
 
      if (res != ERROR_SUCCESS) {
        printf("Unable to enum subkey no. %d \n", (int)i);
        printf("Error Code %d", (int)res);        
        RegCloseKey(key);
        return res;
      }
      
      res = RegOpenKeyEx(key, subkeyName, 0, KEY_READ, &subkey);
      
      if (res != ERROR_SUCCESS) {
        _tprintf(_T("Unable to open subkey %s \n"), subkeyName);
        printf("Error Code %d", (int)res);        
        RegCloseKey(key);
        return res;
      }
      
      res = RegQueryValueEx(subkey, _T("RuntimeLib"), 0, 0, (LPBYTE)path, &dwData);
      
      if (res != ERROR_SUCCESS) {
        printf("Unable to query subkey value\n");
        printf("Error Code %d", (int)res);        
        RegCloseKey(subkey);
        RegCloseKey(key);
        return res;
      }
      
      RegCloseKey(subkey);
      
      found = 1;
      i++;
    }
  }
      
  RegCloseKey(key);
  
  return found;
}

Nicht über Kommentare und Includes (etc) wundern, war mal für jmd. anderen gedacht, der ein ähnliches Problem hatte.

Gruß Der Anmeldeboykottierer
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben