来自Java的DLL调用返回UnsatisfiedLinkError

时间:2014-06-27 09:32:28

标签: java eclipse dll java-native-interface

编辑:问题已解决

我创建了一个新项目并导入了源文件。 (在尝试了太多选项之后,项目配置是错误的。)似乎我混淆了load和loadlibrary函数。 load需要一个包含文件后缀的绝对路径,例如:

static { System.load("c:/windows/system32/jnpout32.dll");}

尝试从Eclipse(Windows 7,Java SE1.7)中的Java调用jnpout32.dll(http://www.hytherion.com/beattidp/comput/pport.htm)时收到错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: EEGTrigger.ioPort.Out32(SS)V
at EEGTrigger.ioPort.Out32(Native Method)
at EEGTrigger.pPort.setAllDataBits(pPort.java:53)
at EEGTrigger.pPort.<init>(pPort.java:19)
at EEGTrigger.EEGTrigger.main(EEGTrigger.java:11)

dll文件位于System32,src文件夹和C:\ Users [user] \ AppData \ Local(由System.getenv()指示)

在用户条目下的类路径中,文件也已加载

jnpout32.dll - \[Project]\src\[Project]\

,它在Package Explorer中的Referenced Libraries下可见

这两行都不起作用:

static { System.loadLibrary("jnpout32"); }
static { System.load("c:/windows/system32/jnpout32"); }

(。按java.lang.UnsatisfiedLinkError - JNI中的建议加载)

我已经确认(基于java.lang.UnsatisfiedLinkError

System.getProperty("java.library.path")

返回system32路径。

java项目的完整代码(我只创作了EEGTrigger类。其余的都是dll。):

package EEGTrigger;    

public class EEGTrigger {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("Starting trigger...");

        pPort lpt1 = new pPort();


        testProtocol(lpt1);


    }

    private static void testProtocol(pPort lpt1) {
        // TODO Auto-generated method stub

        short selectTrigger = 0;

        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        selectTrigger = 1;
        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        selectTrigger = 2;
        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        selectTrigger = 3;
        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        selectTrigger = 4;
        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        selectTrigger = 0;
        sendPulse(lpt1, selectTrigger);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @param lpt1
     */
    public static void sendPulse(pPort lpt1, short selectTrigger) {

        short trigger = 0;

        short targetTrigger = 255;
        short stimulusOnsetAsynchrony = 64;
        short trialOnsetTrigger = 32;
        short triggerOff = 0;

        switch (selectTrigger) { 
            case 1 :    trigger = targetTrigger;
                        break;

            case 2 :    trigger = stimulusOnsetAsynchrony;
                        break;

            case 3 :    trigger = trialOnsetTrigger;
                        break;

            case 4 :    trigger = triggerOff;
                        break;

            default :   trigger = triggerOff;
                        break;
        }

        lpt1.output(trigger);

        try {
            Thread.sleep(50);   // 50 milliseconds
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        lpt1.output(triggerOff);

    }

}


package EEGTrigger;

/* Definitions in the build of jnpout32.dll are:            */
/*   short _stdcall Inp32(short PortAddress);               */
/*   void _stdcall Out32(short PortAddress, short data);    */


public class ioPort
{
    // declare native methods of 'jnpout32.dll'

    // output a value to a specified port address
    public native void Out32(short PortAddress, short data);

    // input a value from a specified port address
    public native short Inp32(short PortAddress);

    // load 'jnpout32.dll'
    static { System.loadLibrary("jnpout32");}
    //static { System.load("c:/windows/system32/jnpout32"); }
}

package EEGTrigger;

// ** Derived from information provided on the web by Dr. Kenneth G. Schweller,
// ** ( http://web.bvu.edu/faculty/schweller/ ) and his Mars Rover project page.

public class pPort
{
   ioPort pp;                   // wrapper class for 'Jnpout32.dll'
                               // with methods:
                               //    int Out32(int port, int value);
                               //    int Inp32(int port);
   short portAddress;            // address of data port
   short currentVal;             // current value of port bits

   public pPort()
   {
      pp = new ioPort();
      portAddress = (short)0x378;     // Hex Address of Data Byte of PC Parallel Port
      setAllDataBits((short)0);       // initialize port bits to 0
      currentVal = 0x00;
   }

   // wrap ParallelPort output method
   public void output(short port, short value)
   {
      pp.Out32(port, value);
   }

   // wrap ParallelPort input method
   public short input(short port)
   {
      return pp.Inp32(port);
   }

    // output to default Data port
    public void output(short value)
    {
      pp.Out32(portAddress, value);
    }

    // input from default Data port
    public short input()
    {
      return pp.Inp32(portAddress);
    }


  /**
   * set all bits on Data port to zero
   **/
   public void setAllDataBits(short value)
   {
      pp.Out32(portAddress, value);
      currentVal = value;
   }


   // For users who prefer dealing with Pin numbers
   //    Set Pin <pin> to <value>
   public void setPin(short pin, short value)
   {
      if (pin >= 2 && pin <= 9)
         // just set the corresponding Data bit to indicted value
         setDataBit((short)(pin-2), value);
   }


   /**
    * Set Data Bit at selected index to a value of 1 or 0
    * while preserving current values of all other Data bits
    **/
   void setDataBit(short index, short value)
   {
      switch(index)
      {
         case 0:
           if (value==0)                        //  Set Data[0] to 0

              currentVal = (short) (currentVal & 0xFE);
                                                       //      aaaa aaaa  currentVal
                                                //  AND 1111 1110  mask
                                                //      =========
                                                //      aaaa aaa0  new currentVal

           else                                 //  Set Data[0] to 1

              currentVal = (short) (currentVal | 0x01);
                                                        //      aaaa aaaa   currentVal
                                                //  OR  0000 0001   mask
                                                //      =========
                                                //      aaaa aaa1   new currentVal
           break;
         case 1:
           if (value==0)
              currentVal = (short) (currentVal & 0xFD);
                                                        //  currentVal = aaaa aa0a
           else
              currentVal = (short) (currentVal | 0x02);
                                                        //  currentVal = aaaa aa1a
           break;
         case 2:
           if (value==0)
              currentVal = (short) (currentVal & 0xFB);
                                                        //  currentVal = aaaa a0aa
           else
              currentVal = (short) (currentVal | 0x04);
                                                        //  currentVal = aaaa a1aa
           break;
         case 3:
           if (value==1)
              currentVal = (short) (currentVal & 0xF7);
                                                        //  currentVal = aaaa 0aaa
           else
              currentVal = (short) (currentVal | 0x08);   //  currentVal = aaaa 1aaa
           break;
         case 4:
           if (value==0)
              currentVal = (short) (currentVal & 0xEF);
                                                        //  currentVal = aaa0 aaaa
           else
              currentVal = (short) (currentVal | 0x10);   //  currentVal = aaa1 aaaa
           break;
         case 5:
           if (value==0)
              currentVal = (short) (currentVal & 0xDF);
                                                        //  currentVal = aa0a aaaa
           else
              currentVal = (short) (currentVal | 0x20);   //  currentVal = aa1a aaaa
           break;
         case 6:
           if (value==0)
              currentVal = (short) (currentVal & 0xBF);
                                                        //  currentVal = a0aa aaaa
           else
              currentVal = (short) (currentVal | 0x40);   //  currentVal = a1aa aaaa
           break;
             case 7:
           if (value==0)
              currentVal = (short) (currentVal &  0x7F);
                                                        //  currentVal = 0aaa aaaa
           else
              currentVal = (short) (currentVal | 0x80);   //  currentVal = 1aaa aaaa
           break;

         default:
           System.out.println("index must be 0 - 7");
      }
      pp.Out32(portAddress, currentVal);
   }


}

以下问题在这方面没有帮助或不适用:

java.lang.UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError in Linux

Java.lang.UnsatisfiedLinkError in eclipse

java.lang.UnsatisfiedLinkError: dbopen

JNI java.lang.UnsatisfiedLinkError

1 个答案:

答案 0 :(得分:0)

您没有提供有关您可能获得UnsatisfiedLinkError的原因的详细信息。尝试附加完整的堆栈跟踪。

只要在JVM通过java -Djava.library.path =“%WINDIR%/ system32 /”

启动时设置java.library.path,

System.loadLibrary(“jnpout32”)就是正确的

如果要使用System.load,则应该执行类似System.load(“c:/ windows / system32 /”+ System.mapLibraryName(“jnpout32”))的操作,以生成本机库名称和扩展名。< / p>

如果您正确使用它们并且两者都继续失败,那么您的错误就像缺少的依赖库一样。