【问题标题】:Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: testmydll.TestDLL.a()I线程“AWT-EventQueue-0”中的异常 java.lang.UnsatisfiedLinkError: testmydll.TestDLL.a()I
【发布时间】:2013-06-22 11:21:45
【问题描述】:

我正在尝试从 Java 调用测试 DLL。

我正在使用

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.*;

类被声明为

   class TestDLL {
   public native int a();
   public native int DoBeep();
   public native int PenniesToCoins();

   static { System.loadLibrary("PenniesLib");}

  // required to work with JDK 6 and JDK 7 ????????
  // I included this because it was in a few examples with the comment above
  // but it doesn't seem to make any difference 
  public static void main(String[] args){
 }
}

我在开始测试的框架上有一个按钮

void button1_actionPerformed(ActionEvent e) {
 int i;
 TestDLL t = new TestDLL();
 i= t.a();
 }
}

程序崩溃

      i= t.a();


Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError:  testmydll.TestDLL.a()I
at testmydll.TestDLL.a(Native Method)
at testmydll.TestMyDLL.button1_actionPerformed(TestMyDLL.java:85)

我知道库加载正常。将其名称更改为“PenniesLibX”会产生错误。

我已经从 Delphi 程序中测试了这个 DLL,并且调用它可以工作。

我已经用 DLL Export Viewer 检查了导出的函数

a   0x00411ff4  0x00011ff4  1 (0x1) PenniesLib.dll  C:\WINXP\system32  PenniesLib.dll   Exported Function   
DoBeep  0x00411fe8  0x00011fe8  2 (0x2) PenniesLib.dll  C:\WINXP\system32\PenniesLib.dll    Exported Function   
PenniesToCoins  0x00411f7c  0x00011f7c  3 (0x3) PenniesLib.dll  C:\WINXP\system32\PenniesLib.dll    Exported Function   

帮助非常感谢

我把它改写成

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.*;


 class TestDLL {
   public native int a();
   public native int DoBeep();
   public native int PenniesToCoins();

   static { System.loadLibrary("PenniesLib");}

 }


public class TestThisDLL {

  public static void main( String args[] ) {
      System.out.println("Start of DLL test");
      TestDLL t = new TestDLL();
      int i = t.a();
      System.out.println("DLL response is " + String.valueOf(i));
  }
}

Delphi DLL 代码是

{ Copyright © 2001 Delphi 6 Developer's Guide Xavier Pacheco
   and Steve Teixeira }

{ DoBeep and a added  for testing}

library PenniesLib;
{$DEFINE PENNIESLIB}
uses
  SysUtils,
  Classes,
  PenniesInt;

function PenniesToCoins(TotPennies: word; CoinsRec: PCoinsRec): word; StdCall;
begin
  Result := TotPennies;  // Assign value to Result
  { Calculate the values for quarters, dimes, nickels, pennies }
  with CoinsRec^ do
  begin
    Quarters    := TotPennies div 25;
    TotPennies  := TotPennies - Quarters * 25;
    Dimes       := TotPennies div 10;
    TotPennies  := TotPennies - Dimes * 10;
    Nickels     := TotPennies div 5;
    TotPennies  := TotPennies - Nickels * 5;
    Pennies     := TotPennies;
  end;
end;

function DoBeep: word; StdCall
begin
    Beep;
    Result:=55;
end;

function a: word; StdCall
begin
    Beep;
    Result:=88;
end;

{ Export the function by name }
exports
  PenniesToCoins, DoBeep, a;
end.

【问题讨论】:

  • 你有DLL的源代码吗?
  • 为什么 main 是空的,为了更好的帮助,尽快发布一个 SSCCE,简短,可运行,可编译,Swing Gui 必须在 Initial Thread 上创建
  • 我已将 Delphi 源添加到帖子中
  • 我已经把它改写成非摇摆程序了
  • 我认为问题在于我天真地假设您可以轻松地从 Java 调用普通的 DLL。 pacifier.com/~mmead/jni/delphi/JEDI/DOCS/delphi-jni-1.html 解释说 Java 原生接口使用自己的命名约定,并且 JNI DLL 必须专门编写。有没有从 Java 调用标准 DLL 的简单方法?

标签: java swing delphi dll jna


【解决方案1】:

您没有按照应有的方式包装本机库。实际上,您没有在问题的代码中使用任何 JNA。关键是你必须调用 Native.loadLibrary。

您的 Java 代码应如下所示:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;

public class TestThisDLL {
    public interface PenniesLib extends StdCallLibrary {
        PenniesLib INSTANCE = (PenniesLib) Native.loadLibrary(
            "PenniesLib", PenniesLib.class);
        int a();
    }

    public static void main(String[] args) {
        int value = PenniesLib.INSTANCE.a();
        System.out.println(value);
    }
}

请注意,我冒昧地假设您将在 Delphi 代码中将 Word 更改为 Integer。由于 Java 没有无符号类型,而且 16 字节类型在 1990 年代如此流行,我认为 32 位有符号整数最有意义。

【讨论】:

  • 我很高兴听到它,并感谢您的接受。我无法让我的 Java JVM 加载已编译的类,但我有理由相信这只是一个问题,因为我完全缺乏关于如何运行 Java 的知识。问题中的代码是对常见 JNA 示例的简单修改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-12
  • 2012-04-06
  • 1970-01-01
  • 2013-04-28
  • 2015-10-23
  • 1970-01-01
相关资源
最近更新 更多