我试图理解为什么我的代码在不同的操作系统中运行时挂起,我不得不调试不同的eclipse插件。我在某个Java文件中看到以下代码:
Library.loadLibrary("swt")
基于什么是Java中的本机方法,它们应该在哪里使用?我知道本机方法是用来执行用不同编程语言编写的函数的。但是我有两个问题:
- 当
loadLibrary
与输入"swt"
一起被调用时,实际发生了什么?哪里loadLibrary
寻找SWT库,我怎么能改变它?在Linux中获取库的等效命令是什么(我猜是一些共享库)? 考虑以下代码:
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文件是否包含该符号。