2016-06-06 2 views
1

Я пытаюсь использовать файл jar в C++-программе с использованием JNI.0xC0000005: Место для обнаружения нарушения доступа 0x0000000000000000

Я сделал это:

// TestJavaToCpp.cpp : Defines the entry point for the console application. 
// 

#include <jni.h> 
#include "stdafx.h" 
#include <windows.h> 
#include <stdio.h> 
#include <iostream> 

using namespace std; 


int main() 
{ 
    JavaVM *jvm; 
    JNIEnv *env; 
    JavaVMInitArgs vm_args; 
    JavaVMOption options; 
    options.optionString = "-Djava.class.path=HelloWorld.jar"; 
    vm_args.version = JNI_VERSION_1_6; 
    vm_args.nOptions = 1; 
    vm_args.options = &options; 
    vm_args.ignoreUnrecognized = 0; 
    int ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
    if (ret == 0) { 
     jclass cls = env->FindClass("HelloWorld"); 
     if (cls != 0) { 
      jmethodID meth = env->GetStaticMethodID(cls, "Hello", "([Ljava/lang/String;)V"); 
      jarray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), 0); 
      env->CallStaticVoidMethod(cls, meth, args); 
     } 
    } 
    return ret; 
} 

Когда HelloWorld.jar находится в той же папке, где находится исполняемый файл. Однако, я постоянно получаю ошибку

0xC0000005: нарушение прав доступа для чтения расположение 0x0000000000000000

, когда он пытается создать JVM.

EDIT 1: Теперь код выглядит следующим образом:

// TestJava.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <jni.h> 
#include <Windows.h> 
#include <stdio.h> 
#include <iostream> 

using namespace std; 

#define CLEAR(x) memset(&x, 0, sizeof(x)) 

int main() 
{ 
    JavaVM *jvm(0); 
    JNIEnv *env(0); 
    JavaVMInitArgs vm_args; 
    CLEAR(vm_args); 
    JavaVMOption options; 
    CLEAR(options); 

    options.optionString = "-Djava.class.path=HelloWorld.jar"; 
    options.extraInfo = 0; 
    vm_args.version = JNI_VERSION_1_8; 
    vm_args.nOptions = 1; 
    vm_args.options = &options; 
    vm_args.ignoreUnrecognized = 0; 
    int ret = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); 

    return 0; 
} 

Я оставил только код, который на самом деле создает виртуальную машину. Когда она будет работать, я пойду,

И теперь я заметил ошибки, что обнаружился раньше, но я не обратил на них внимания:

«TestJava.exe» (Win32): Loaded 'C: \ Users \ amitb \ OneDrive \ מסמכים \ Visual Studio 2015 \ Projects \ TestJava \ Debug \ TestJava.exe'. Загружены символы.

«TestJava.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ ntdll.dll». Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ kernel32.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ KernelBase.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ apphelp.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ vcruntime140d.dll'. Не удается найти или открыть файл PDB . 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ ucrtbased.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружен 'C: \ Program Files (x86) \ Java \ jdk1.8.0_91 \ jre \ bin \ client \ jvm.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ advapi32.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ user32.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ msvcrt.dll'. Не удается найти или открыть файл PDB.

«TestJava.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ gdi32.dll». Не удается найти или открыть файл PDB. 'TestJava.exe '(Win32): Загружен ' C: \ Windows \ SysWOW64 \ wsock32.dll '. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ winmm.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ sechost.dll'. Не удается найти или открыть файл PDB.

«TestJava.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ psapi.dll». Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ version.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ winmmbase.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ msvcr100.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ rpcrt4.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ cfgmgr32.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ ws2_32.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ sspicli.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ cryptbase.dll'. Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ bcryptprimitives.dll'. Не удается найти или открыть файл PDB . 'TestJava.exe' (Win32): Загружен 'C: \ Windows \ SysWOW64 \ imm32.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружен 'C: \ Program Files (x86) \ Java \ jdk1.8.0_91 \ jre \ bin \ verify.dll'. Не удается найти или открыть файл PDB .

'TestJava.exe' (Win32): Загружен 'C: \ Program Files (x86) \ Java \ jdk1.8.0_91 \ jre \ bin \ java.dll'. Не удается найти или открыть файл PDB .

'TestJava.exe' (Win32): Загружен 'C: \ Program Files (x86) \ Java \ jdk1.8.0_91 \ jre \ bin \ zip.dll'. Не удается найти или открыть файл PDB .

Исключение брошено в 0x025A0202 в TestJava.exe: 0xC0000005: Доступ чтения нарушение расположения 0x00000000.

«TestJava.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ shell32.dll». Не удается найти или открыть файл PDB. 'TestJava.exe' (Win32): Загружено

'C: \ Windows \ SysWOW64 \ windows.storage.dll'. Не удается найти или открыть файл PDB .

'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ combase.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ shlwapi.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ kernel.appcore.dll'. Не удается найти или открыть файл PDB .

«TestJava.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ SHCore.dll». Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): Загружено 'C: \ Windows \ SysWOW64 \ powrprof.dll'. Не удается найти или открыть файл PDB.

'TestJava.exe' (Win32): загружен 'C: \ Windows \ SysWOW64 \ profapi.dll'. Не удается найти или открыть файл PDB.

Поток 0x2760 вышел с кодом 0 (0x0).

Нить 0x494c вышла с кодом 0 (0x0).

Произошла нить 0x3368 с кодом 0 (0x0).

Нить 0x2e48 имеет с кодом 0 (0x0).

Поток 0x3d5c вышел с кодом 0 (0x0).

Поток 0x3b2c вышел с кодом 0 (0x0).

Нить 0x4490 имеет код 0 (0x0).

Поток 0x3bb4 вышел с кодом 0 (0x0). Поток 0x4d18 вышел с кодом 0 (0x0).

thread 0x2cac имеет код 0 (0x0).

Нить 0x4ec8 имеет с кодом 0 (0x0).

Программа '[18476] TestJava.exe' имеет с кодом 0 (0x0).

Посмотрите на смелое предложение. Это когда исключение бросает ...

+0

Что делает 'GetStaticMethodID()', 'NewObjectArray()' и FindClass ("java/lang/String") 'return? Ваш код просто * надеется, что они работают. –

+0

Сбой перед статусом if в строке int ret = JNI_CreateJavaVM (& jvm, (void **) & env, & vm_args); – kitsuneFox

+0

Попробуйте ответы здесь: http://stackoverflow.com/questions/27435647/jni-createjavavm-crash-my-program-without-any-message-or-exception – samgak

ответ

1

Вам нужно установить options.extraInfo = 0;

Я хотел бы сделать все это для хорошей меры. Оборонительное программирование требует, чтобы все было инициализировано.

#define CLEAR(x) memset(&x, 0, sizeof(x)) 
JavaVM *jvm(0); 
JNIEnv *env(0); 
JavaVMInitArgs vm_args; 
CLEAR(vm_args); 
JavaVMOption options; 
CLEAR(options); 

Примечание:

typedef struct JavaVMOption { 
    char *optionString; 
    void *extraInfo; 
} JavaVMOption; 

EDIT: Ничего из этого не оказалось проблемой. Решение в комментариях - JVM бросает исключения нарушения прав доступа. Они пойманы и обработаны, но не раньше, чем Visual Studio заставит вас поверить, что есть проблема.

+0

все еще ничего ... Пожалуйста, обратите внимание на отредактированный вопрос – kitsuneFox

+0

Я скомпилировал и запустил ваш код в Visual Studio 2013 без ошибок. Единственное изменение, которое я должен был сделать, это следующее: vm_args.version = JNI_VERSION_1_6; Обратите внимание, что я использую Java 1.7 не 1.8, но я не уверен, почему это имеет значение. – Wheezil

+0

Еще одно замечание. JVM будет исключать нарушения прав доступа (и обрабатывать!) Как часть управления внутренней памятью. Просто запустите программу в отладчике, но сначала выберите «Debug-> Exceptions ...» и отключите «break on Win32 exceptions throw». Установите точку останова при «возврате 0». Он туда попал? Если это так, ты золотой. Эти ложные нарушения доступа сведят вас с ума. – Wheezil