Получение EXCEPTION_ACCESS_VIOLATION от JVM при попытке доступа к функции DLL - PullRequest
0 голосов
/ 24 марта 2019

Я пытаюсь получить доступ к сторонней DLL из моего собственного файла DLL, но получаю нарушение прав доступа к памяти JVM при вызове моей собственной DLL с помощью JNI.

Сторонняя DLL, которую я пытаюсь вызватьтакое cfint64.dll.Для проблем совместимости я создаю свою собственную dll для доступа к dll третьей стороны.

Я не знаю, какой компилятор использовался для стороннего cfint64.dll, но он должен быть для 64-битных машин.

Со своей стороны я создаю свою собственную DLL: g ++ -I "% JAVA_HOME% \ include" -I "% JAVA_HOME% \ include \ win32" -shared -o dll3minterface.dll DLL3MInterface.cpp

Я знаю, что сторонняя DLL имеет подпись функции ниже:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class dllCommunication */

#ifndef _Included_dllCommunication
#define _Included_dllCommunication
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     dllCommunication
 * Method:    nJavaInitInstance
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_dllCommunication_nJavaInitInstance
  (JNIEnv *, jobject, jstring);



#ifdef __cplusplus
}
#endif
#endif

Файл заголовка, который я создал, находится ниже:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_artificialmedgui_coderdx_DLL3MInterface */

#ifndef _Included_com_artificialmedgui_coderdx_DLL3MInterface
#define _Included_com_artificialmedgui_coderdx_DLL3MInterface
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_artificialmedgui_coderdx_DLL3MInterface
 * Method:    nJavaInitInstance
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_artificialmedgui_coderdx_DLL3MInterface_nJavaInitInstance(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

Мой файл .cpp, который вызываетнарушение доступа к памяти ниже.Обратите внимание, что строка, вызывающая ошибку - это funcCall (inJNIStr) ;.Если я закомментирую этот вызов функции, программа завершится без ошибок.

#include <windows.h>
#include <jni.h>       // JNI header provided by JDK
#include <iostream>    // C++ standard IO header
#include "com_artificialmedgui_coderdx_DLL3MInterface.h"  // Generated
using namespace std;

typedef int (__stdcall* initInstanceFunc)(jstring);

JNIEXPORT jint JNICALL Java_com_artificialmedgui_coderdx_DLL3MInterface_nJavaInitInstance(JNIEnv *env, jobject, jstring inJNIStr) {
    // Step 1: Convert the JNI String (jstring) into C-String (char*)
   const char *inCStr = env->GetStringUTFChars(inJNIStr, NULL);



    HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\workspace\\AMI3MDLLInterface\\resources\\cfint64.dll");

  if (!hGetProcIDDLL) {
    std::cout << "could not load the dynamic library" << std::endl;
    return EXIT_FAILURE;
  }
  else{
      std::cout << "Loaded cfint64.dll library!!!!" << std::endl;
  }

  // resolve function address here
  initInstanceFunc funcCall = (initInstanceFunc)GetProcAddress(hGetProcIDDLL, "Java_dllCommunication_nJavaInitInstance");
     if (*funcCall != NULL) {
      funcCall(inJNIStr);
  }
  else{
      std::cout << "Function is invalid" << std::endl;
  }


       return 1; //Testing
    }

Я могу загрузить стороннюю версию cfint64.dll, но при вызове одной из ее функций, таких как funcCall (inJNIStr);выдает ошибку ниже.
Может быть, я не передаю правильный тип данных String из моего файла .cpp при вызове функции cfint64.dll?Я не программист на C ++, поэтому любые идеи, вызывающие проблемы, приветствуются.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=12276, tid=11080
#
# JRE version: Java(TM) SE Runtime Environment (10.0.1+10) (build 10.0.1+10)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.1+10, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  0x0000000000000000
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  S U M M A R Y ------------

Command Line: com.artificialmedgui.coderdx.DLL3MInterface

Host: Intel(R) Core(TM) i7-4720HQ CPU @ 2.60GHz, 8 cores, 15G,  Windows 10 , 64 bit Build 17134 (10.0.17134.648)
Time: Sun Mar 24 14:15:30 2019 Eastern Daylight Time elapsed time: 1 seconds (0d 0h 0m 1s)

---------------  T H R E A D  ---------------

Current thread (0x000001421b910800):  JavaThread "main" [_thread_in_native, id=11080, stack(0x0000003371700000,0x0000003371800000)]

Stack: [0x0000003371700000,0x0000003371800000],  sp=0x00000033717ff258,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.artificialmedgui.coderdx.DLL3MInterface.nJavaInitInstance(Ljava/lang/String;)I+0
j  com.artificialmedgui.coderdx.DLL3MInterface.main([Ljava/lang/String;)V+17
v  ~StubRoutines::call_stub

siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), data execution prevention violation at address 0x0000000000000000


Register to memory mapping:

RIP=0x0000000000000000 is an unknown value
RAX=0x00000006d0a4b6c0 is an oop
java.lang.String 
{0x00000006d0a4b6c0} - klass: 'java/lang/String'
RBX={method} {0x000001423eb204a8} 'nJavaInitInstance' '(Ljava/lang/String;)I' in 'com/artificialmedgui/coderdx/DLL3MInterface'
RCX=0x00000033717ff380 is pointing into the stack for thread: 0x000001421b910800
RDX=0x0000000000000002 is an unknown value
RSP=0x00000033717ff258 is pointing into the stack for thread: 0x000001421b910800
RBP=0x00000033717ff2d0 is pointing into the stack for thread: 0x000001421b910800
RSI=0x0000000000000002 is an unknown value
RDI=0x00000033717ff380 is pointing into the stack for thread: 0x000001421b910800
R8 =0x0000000000000000 is an unknown value
R9 =0x0000000000000000 is an unknown value
R10=0x0000000000000002 is an unknown value
R11=0x00000033717fef80 is pointing into the stack for thread: 0x000001421b910800
R12=0x0000000000000000 is an unknown value
R13={method} {0x000001423eb204a8} 'nJavaInitInstance' '(Ljava/lang/String;)I' in 'com/artificialmedgui/coderdx/DLL3MInterface'
R14=0x00000033717ff388 is pointing into the stack for thread: 0x000001421b910800
R15=0x000001421b910800 is a thread

1 Ответ

0 голосов
/ 25 марта 2019

Я решаю эту проблему.Возможно, я не прояснил это с самого начала, но моя JNI DLL вызывает другую стороннюю JNI DLL.Поэтому, когда вы вызываете JNI DLL из вашего Java-кода, вам просто нужно передать фактические параметры.Я предполагаю, что компоновщик JVM добавит дополнительные параметры при вызове фактической функции DLL.В любом случае из моей DLL мне просто нужно было передать эти дополнительные параметры, которые компоновщик JVM, вероятно, передал бы.

Чтобы вызвать эту вторую функцию JNI DLL:

Wrong:
typedef int (__stdcall* initInstanceFunc)(jstring);

Works:
typedef int (__stdcall* initInstanceFunc)(JNIEnv*,jobject,jstring);
...
funcCall(env,obj,inJNIStr);
...