关于Java中加载库和本机方法的几个问题



我试图理解为什么我的代码在不同的操作系统中运行时挂起,我不得不调试不同的eclipse插件。我在某个Java文件中看到以下代码:

Library.loadLibrary("swt")

基于什么是Java中的本机方法,它们应该在哪里使用?我知道本机方法是用来执行用不同编程语言编写的函数的。但是我有两个问题:

  1. loadLibrary与输入"swt"一起被调用时,实际发生了什么?哪里loadLibrary寻找SWT库,我怎么能改变它?在Linux中获取库的等效命令是什么(我猜是一些共享库)?
  2. 考虑以下代码:
public static final native void _gtk_widget_destroy(long /*int*/ widget);
public static final void gtk_widget_destroy(long /*int*/ widget) {
lock.lock();
try {
_gtk_widget_destroy(widget);
} finally {
lock.unlock();
}
}

_gtk_widget_destroy方法是原生的。这是否意味着在另一种语言(可能是C语言)中有一个称为_gtk_widget_destroy的方法?我如何知道这个方法来自哪个库(可能是SWT)?

System.loadLibrary("X")使用System#mapLibraryName来构造实际的库名。在Linux上是libX.so,在Mac上是libX.dylib,在Windows上是libX.dll

然后在java.library.path(VM属性)的每个条目中搜索具有该名称的库。

对于第二个问题:您还需要周围类的完整名称空间和类名。快速搜索告诉我该方法的全名是org.eclipse.swt.internal.gtk.GTK#_gtk_widget_destroy。现在,有两个选项:

  • libswt.so调用RegisterNatives将此方法绑定到函数指针(通常在其JNI_OnLoad方法中)。事实并非如此。
  • 它使用通用的名称混淆方案,这将导致一个名称为Java__org_eclipse_swt_internal_gtk_GTK_1gtk_1widget_1destroy的符号。似乎开发人员已经将长名称抽象到宏中。您可以使用标准nm工具来确定给定的。so文件是否包含该符号。

相关内容

  • 没有找到相关文章

最新更新