调用本地方法时返回java.lang.UnsatisfiedLinkError

 2023-01-20    382  

问题描述

我试图为第三方DLL制作Java包装.我创建了自己的DLL,在JNI和第三方DLL之间充当了中间人.在Java中,我可以加载此dll,但是返回了错误java.lang.UnsatisfiedLinkError: sixense.Sixense.init()Z.什么可能导致此错误,如何正确调试?

main.java:

调用本地方法时返回java.lang.UnsatisfiedLinkError

package sixense_test;

import sixense.ControllerData;
import sixense.Sixense;

public class Main {

    public static ControllerData[] controllers = new ControllerData[4];
    public static boolean quit;

    public static void main(String[] args) {
        if(Sixense.init()) {
            Sixense.setActiveBase(0);
            Sixense.getAllNewestData(controllers);
            System.out.println("X: " + controllers[0].pos[0] + "Y: " + controllers[0].pos[1] + "Z: " + controllers[0].pos[2]);
        }
    }
}

sixense.java:

package sixense;

public class Sixense {
    public static native boolean init();
    public static native boolean exit();
    public static native int getMaxBases();
    public static native boolean setActiveBase( int base_num );
    public static native boolean isBaseConnected( int base_num );
    public static native int getMaxControllers();
    public static native int getNumActiveControllers();
    public static native boolean isControllerEnabled( int controller_id );
    public static native boolean getAllNewestData( ControllerData[] all_data );
    public static native boolean getAllData( int index_back, ControllerData[] all_data );
    public static native boolean getNewestData( int controller_id, ControllerData data );
    public static native boolean getData( int controller_id, int index_back, ControllerData all_data );
    public static native int getHistorySize();
    public static native boolean setFilterEnabled( boolean on_or_off );
    public static native boolean getFilterEnabled();
    public static native boolean setFilterParams( float near_range, float near_val, float far_range, float far_val );
    public static native boolean getFilterParams( float[] params );
    public static native boolean triggerVibration( int controller_id, int duration, int pattern_id );
    public static native boolean autoEnableHemisphereTracking( int controller_id );
    public static native boolean setHighPriorityBinding( boolean on_or_off );
    public static native boolean getHighPriorityBinding();
    public static native boolean setBaseColor( int red, int green, int blue );
    public static native boolean getColorBase( int[] colors );
    static {
        System.loadLibrary("Sixense_Java");
    }
}

sixense_sixense.cpp的摘录:

#include <jni.h>
#include <sixense.h>
#include "sixense_Sixense.h"

JNIEXPORT jboolean JNICALL Java_sixense_Sixense_init(JNIEnv *env, jclass obj) {
    int i;
    i = sixenseInit();
    return (i == -1) ? JNI_FALSE : JNI_TRUE;
}

sixense_sixense.h的摘录:

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

#ifndef _Included_sixense_Sixense
#define _Included_sixense_Sixense
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     sixense_Sixense
 * Method:    init
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_sixense_Sixense_init
  (JNIEnv *, jclass);

从Dumpbin输出:

File Type: DLL

  Section contains the following exports for Sixense_Java.dll

    00000000 characteristics
    4FFBC481 time date stamp Tue Jul 10 01:58:25 2012
        0.00 version
           1 ordinal base
          23 number of functions
          23 number of names

    ordinal hint RVA      name

          1    0 00001D10 Java_sixense_Sixense_autoEnableHemisphereTracking@12
          2    1 000011A0 Java_sixense_Sixense_exit@8
          3    2 00001A40 Java_sixense_Sixense_getAllData@16
          4    3 000019A0 Java_sixense_Sixense_getAllNewestData@12
          5    4 00001DC0 Java_sixense_Sixense_getColorBase@12
          6    5 00001B30 Java_sixense_Sixense_getData@20
          7    6 00001BD0 Java_sixense_Sixense_getFilterEnabled@8
          8    7 00001C40 Java_sixense_Sixense_getFilterParams@12
          9    8 00001D60 Java_sixense_Sixense_getHighPriorityBinding@8
         10    9 00001B90 Java_sixense_Sixense_getHistorySize@8
         11    A 000011C0 Java_sixense_Sixense_getMaxBases@8
         12    B 00001210 Java_sixense_Sixense_getMaxControllers@8
         13    C 00001AE0 Java_sixense_Sixense_getNewestData@16
         14    D 00001220 Java_sixense_Sixense_getNumActiveControllers@8
         15    E 00001180 Java_sixense_Sixense_init@8
         16    F 000011F0 Java_sixense_Sixense_isBaseConnected@12
         17   10 00001230 Java_sixense_Sixense_isControllerEnabled@12
         18   11 000011D0 Java_sixense_Sixense_setActiveBase@12
         19   12 00001D90 Java_sixense_Sixense_setBaseColor@20
         20   13 00001BA0 Java_sixense_Sixense_setFilterEnabled@12
         21   14 00001C00 Java_sixense_Sixense_setFilterParams@24
         22   15 00001D30 Java_sixense_Sixense_setHighPriorityBinding@12
         23   16 00001CE0 Java_sixense_Sixense_triggerVibration@20

  Summary

        1000 .bss
        1000 .data
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        2000 .text

推荐答案

在Java中调用本机函数时,运行时会尝试使用:

  • stdcall式装饰功能:_functionName@n,其中n是参数列表中的字节数,
  • 和cDECL风格未装饰的功能:functionName.

使用mingw编译时,您将获得这两个的混合:mingw将附加@n,但不会预先确定下划线:functionName@n.

解决此问题的方法是告诉ld不要添加后缀,使用–kill-at switch(或-Wl,–kill-at,如果您通过GCC调用).

其他推荐答案

我找到了答案!看来,当Windows中使用JNI时,它会寻找以_Java_开头的函数,而在其他每个平台中都在寻找Java_.为什么是这种情况,而不是写在文档中,我不知道,但它使一切正常工作!

其他推荐答案

java.lang.UnsatisfiedLinkError: no Sixense_Java in java.library.path

看起来Java找不到图书馆,您将其放在正确的位置吗?

您可能需要更改java.library.path,看看 this .

如果要打印它的内容,请使用:

System.out.println( System.getProperties().getProperty("java.library.path"));

这可能会打印很多,您可能需要split(“;”)并自己打印每个条目.

以上所述是小编给大家介绍的调用本地方法时返回java.lang.UnsatisfiedLinkError,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25982.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。