簡體   English   中英

Windows JNI 加載並執行 dll 中的 c++ 代碼錯誤 Z93F725A07423FE1C889F448B33DsfiedLinkError:648B33DsfiedLinkError:6

[英]Windows JNI Loading and executing c++ code in dll error java.lang.UnsatisfiedLinkError:

Answer/Solution: To be clear Jorn Vernee's answer is correct in that when i created my.h file originally i didnt have the package information in the.java class but when my code was executed it did have the package information. .h 文件中的方法名稱最終會在名稱中包含 package 信息。

我有一些 C++ 代碼用於截屏。 我一直在嘗試使用 JNA 和 JNI 從 Java 調用它,但都沒有運氣。 我的最終目標是讓 captureScreen 方法工作。 我創建了一個 getNumber 方法作為一個簡單的測試,沒有傳入任何參數,但即使它也不起作用。

更新我的應用程序作為 64 位應用程序運行,而我的 dll 是 64 位的。 不確定這是否會影響傳入或傳出的參數。

我目前的實現

Java

public class JNIScreenShotTest { 
   static {
  String oldLibraryPath = System.getProperty("java.library.path");
  try{
  //This doesnt work for me it fails on the loadLibrary call and I get an UnsatisfiedLinkError
  //System.setProperty("java.library.path", "C:\\workspace\\com.tdkc.udop\dlls");
  //System.loadLibrary("JNIScreenShot"); 
                               
  //This Manages to load the library without error                         
  System.load("C:\\workspace\\com.tdkc.udop\\dlls\\JNIScreenShot.dll")
  }finally}
      System.setProperty("java.library.path", oldLibraryPath );
  }
 }

  private native void captureScreen(String filePath, int x, int y, int width, int height);

  private native int getNumber();

}

我使用 javac -h 從上面的 class 創建了我的 header 文件

.h 文件

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

    #include "DXGICapture.h"

    #include <stdio.h>
    #include <tchar.h>
    #include <shlobj.h>
    #include <atlconv.h>
    #include <string>

    using namespace std;

    #ifndef _Included_JNIScreenShot
    #define _Included_JNIScreenShot
    #ifdef __cplusplus
    extern "C" {
    #endif
        /*
         * Class:     JNIScreenShot
         * Method:    captureScreen
         * Signature: (Ljava/lang/String;IIII)V
         */
        JNIEXPORT void JNICALL Java_JNIScreenShot_captureScreen
        (JNIEnv*, jobject, jstring, jint, jint, jint, jint);

        /*
     * Class:     JNIScreenShotTest
     * Method:    getNumber
     * Signature: ()I
     */
        JNIEXPORT jint JNICALL Java_JNIScreenShotTest_getNumber
        (JNIEnv*, jobject);

    #ifdef __cplusplus
    }
    #endif
    #endif

C++文件

    // ScreenCapture.cpp : Defines the exported functions for the DLL.
//


#include "JNIScreenShot.h"
#include <iostream>


JNIEXPORT void JNICALL Java_JNIScreenShot_captureScreen
(JNIEnv *env, jobject clz, jstring filePath, jint x, jint y, jint width, jint height) {
    HRESULT hr = S_OK;
    CDXGICapture dxgiCapture;
    jboolean isCopy;
    const char* pszOutputFileName = (env)->GetStringUTFChars(filePath, &isCopy);

    hr = dxgiCapture.Initialize();
    tagScreenCaptureFilterConfig config;

    // set default config
    RtlZeroMemory(&config, sizeof(config));
    config.ShowCursor = 1;
    config.SizeMode = tagFrameSizeMode_AutoSize;

    hr = dxgiCapture.SetConfig(config);
    hr = dxgiCapture.CaptureToFile((LPCTSTR)CA2WEX<>(pszOutputFileName), x, y, width, height);
    if (FAILED(hr))
    {
        printf("Error[0x%08X]: CDXGICapture::CaptureToFile failed.\n", hr);
    }
}

/*
 * Class:     JNIScreenShotTest
 * Method:    getNumber
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_JNIScreenShotTest_getNumber
(JNIEnv *env, jobject clz) {
    return 2;
}

我來自 java 的電話如下

File f = new File("Some file");
int x = some value;
int y = some value;
int width = some value;
int height = some value;

JNIScreenShot jniScreenShot = new JNIScreenShot();
jniScreenShot.(f.getAbsolutePath(), x,y,width,height)

這會產生錯誤 java.lang.UnsatisfiedLinkError: com.tdkc.udop.screencapture.jniScreenShot.captureScreen(Ljava/lang/string;IIII)V

起初我認為我的 captureScreen 中的某些東西失敗了,或者可能是我傳入的數據類型不同。所以我創建了 getNumber 方法作為測試

調用 getNumber() java.lang.UnsatisfiedLinkError: com.tdkc.udop.screencapture.jniScreenShot.getNumber()I 時出現類似錯誤

兩條錯誤消息都引用了 .h 文件中的簽名,所以我知道它找到了 dll 並嘗試調用正確的方法。

花了一些時間查看 UnsatisfiedLinkError 但大多數谷歌搜索結果表明,當庫正在加載時,我已經看到很多包括嘗試使用 System.loadLibrary() 而不是 System.load()

它似乎可以找到方法,因為錯誤包含在 my.h 文件中為每個方法定義的簽名。

在這一點上,我已經嘗試遵循關於 JNI 的一百萬個指南和教程,並且已經 2 天了,我失去了任何幫助,非常感謝。

從你的錯誤信息來看:

java.lang.UnsatisfiedLinkError: com.tdkc.udop.screencapture.jniScreenShot.getNumber()I

您的 class 似乎在 package 中。 但是,您的本地 function 的名稱與此不匹配:

Java_JNIScreenShotTest_getNumber

package 名稱也應編碼為原生 function 的名稱。 從該錯誤消息來看,您的本機 function 的名稱應該是:

Java_com_tdkc_udop_screencapture_jniScreenShot_getNumber

使用-Xlog:library*=trace從 JDK 15 開始),您可以看到 VM 用於查找的確切名稱。 例如:

[0.211s][info][library] Loaded library C:\Program Files\Java\jdk-15\bin\nio.dll, handle 0x00007ffacf0f0000
...
[0.212s][info][library] Found Java_sun_nio_fs_WindowsNativeDispatcher_initIDs in library with handle 0x00007ffacf0f0000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM