5

サードパーティのDLLのJavaラッパーを作成しようとしています。JNIとサードパーティDLLの仲介役として機能する独自のDLLを作成しました。Javaでは、このDLLを正常にロードしますが、エラーjava.lang.UnsatisfiedLinkError: sixense.Sixense.init()Zが返されます。このエラーの原因は何でしょうか。また、適切にデバッグするにはどうすればよいですか。

Main.java:

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);

ダンプビンからの出力:

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
4

3 に答える 3

7

Javaでネイティブ関数を呼び出す場合、ランタイムは以下を使用しようとします。

  • stdcallスタイルの装飾関数:_functionName@n、ここで、nはパラメータリストのバイト数です。
  • およびcdeclスタイルの装飾されていない関数:functionName

MinGWでコンパイルすると、次の2つが混在します。MinGWはを追加しますが@n、アンダースコアを追加しませんfunctionName@n

これを解決する方法は、スイッチを使用して(または、GCCを介して呼び出す場合)ld、サフィックスを追加しないように指示することです。--kill-at-Wl,--kill-at

于 2013-09-29T15:55:43.733 に答える
4

私は答えを見つけました!WindowsでJNIを使​​用すると、_Java_他のすべてのプラットフォームでで始まる関数を検索するようですJava_。なぜこれが当てはまり、ドキュメントに書かれていないのかわかりませんが、すべてが完全に機能します!

于 2012-07-11T03:07:39.643 に答える
1
java.lang.UnsatisfiedLinkError: no Sixense_Java in java.library.path

Javaがライブラリを見つけられないようですが、適切な場所に配置しましたか?

を変更する必要があるかもしれません。これjava.library.pathを見てください。

その内容を印刷したい場合は、以下を使用してください。

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

split(";")これはたくさん印刷するかもしれません、あなたはそれ自身で各エントリーを印刷したいと思うかもしれません。

于 2012-07-10T19:22:30.147 に答える