我为您提供这个,希望能为您节省一些时间和痛苦。
作为我在我的 Windows 64 位工作站上了解 NB Development v7 的经验的一部分,我发现了另一个令人沮丧的冒险,试图让 JNI(Java 本机接口)能力提升并在我的项目中工作。因此,我包含了所需步骤的简短摘要(因为我发现的所有文档对于这些版本的 Windows 和 NetBeans 关于如何执行 JNI 都是完全不正确的)。我花了几天的时间进行实验,并审查了我能找到的每个网页,其中包括这些技术作为关键字搜索。呸!!不好玩。
首先,由于 NetBeans 开发是“所有关于模块的”,如果您正在阅读本文,您可能需要一个或多个模块来执行 JNI 调用。本网站或 Internet 上提供的大部分内容(更不用说 NB7 中的帮助文件)对于这些版本来说要么完全错误,要么过于稀少,以至于对 JNI 专家以外的任何人都毫无用处。
这就是您正在寻找的……“切入正题”-“如何指导”以获取 JNI 调用并在您的 NB7 / Windows 64 位机器上工作。
1) 从您的 NetBeans 模块(不是主机应用程序)中声明您的本地方法,并确保您可以无错误地编译 Java 源代码。
例子:
package org.mycompanyname.nativelogic;
public class NativeInterfaceTest
{
static
{
try
{
if (System.getProperty( "os.arch" ).toLowerCase().equals( "amd64" ) )
System.loadLibrary( <64-bit_folder_name_on_file_system>/<file_name.dll> );
else
System.loadLibrary( <32-bit_folder_name_on_file_system>/<file_name.dll> );
}
catch (SecurityException se) {}
catch (UnsatisfieldLinkError ule) {}
catch (NullPointerException npe) {}
}
public NativeInterfaceTest() {}
native String echoString(String s);
}
请注意我们只加载程序集一次(因为它在静态块中),否则如果尝试再次加载它会抛出异常。还要注意我们名为“echoString”的单个(在此示例中)本机方法。这是我们的 C / C++ 应用程序将要实现的方法,然后通过 JNI 的 majic,我们将从我们的 Java 代码中调用。
2)如果使用 64 位版本的 Windows(我们在这里),我们需要打开 64 位 Visual Studio 命令提示符(相对于标准 32 位版本),并执行“vcvarsall”BAT 文件,以及“amd64”命令行参数,为 64 位工具设置环境。
例子:
<path_to_Microsoft_Visual_Studio_10.0>/VC/vcvarsall.bat amd64
请注意,您可以使用 Microsoft 提供的任何版本的 C/C++ 编译器。我碰巧在我的盒子上安装了 Visual Studio 2005、2008 和 2010,所以我选择使用“v10.0”,但任何支持 64 位开发的都可以正常工作。这里的另一个重要方面是“amd64”参数。
3) 在命令提示符中更改您计算机上的驱动器\ 目录,以便您位于包含您的本机方法声明的文件系统上的完全限定类位置的根目录。
示例:我的本机声明方法的完全限定类名是“org.mycompanyname.nativelogic.NativeInterfaceTest”。由于我们在上面的步骤 1 中成功编译了 Java,我们应该会发现它包含在我们的 NetBeans 模块中,类似于以下内容:
“/build/classes/org/mycompanyname/nativelogic/NativeInterfaceTest.class”
由于下一步,我们需要确保我们的命令提示符直接设置为当前的“/build/classes”。
4) 在这一步中,我们将创建包含 JNI 所需语句的 C/C++ 头文件。在命令提示符中键入以下内容:
javah -jni org.mycompanyname.nativelogic.NativeInterfaceTest
然后按回车。如果您收到任何类型的错误,表明这是一个无法识别的命令,这仅意味着您的 Windows 计算机不知道该命令的 PATH(它位于您的 /bin 文件夹中)。从那里运行命令,或者在调用此应用程序时包含完全限定的路径名,或者设置计算机的 PATH 环境变量以在其搜索中包含该路径。
这应该产生一个名为“org_mycompanyname_nativelogic_NativeInterfaceTest.h”的文件......一个C头文件。如果您以后需要备份,我会制作一份副本。
5) 编辑 NativeInterfaceTest.h 头文件并包含 echoString() 方法的实现。
例子:
JNIEXPORT jstring JNICALL Java_org_mycompanyname_nativelogic_NativeInterfaceTest_echoString
(JNIEnv *env, jobject jobj, jstring js)
{
return((*env)->NewStringUTF(env, "My JNI is up and working after lots of research"));
}
注意你不能简单地返回一个普通的 Java 字符串(因为你现在在 C 中)。您必须告诉传入的 JVM 变量为您创建一个将返回的 Java 字符串。查看以下Oracle 网页以了解其他数据类型以及如何为 JNI 目的创建它们。
6) 关闭并保存对头文件的更改。现在您已经向 Header 添加了一个实现,将文件扩展名从“.h”更改为“.c”,因为它现在是一个正确实现 JNI 所需接口的 C 源代码文件。
示例:NativeInterfaceTest.c
7)我们需要编译新创建的源代码文件并链接它。在命令提示符中键入以下内容:
cl /I"path_to_my_jdks_include_folder" /I"path_to_my_jdks_include_win32_folder" /D:AMD64=1 /LD NativeInterfaceTest.c /FeNativeInterfaceTest.dll /link /machine:x64
例子:
cl /I"D:/Program Files/Java/jdk1.6.0_21/include" /I"D:/Program Files/java/jdk1.6.0_21/include/win32" /D:AMD64=1 /LD NativeInterfaceTest.c /FeNativeInterfaceTest.dll /link /machine:x64
请注意“include”和“include/win32”文件夹路径周围的引号是必需的,因为我的文件夹名称中有空格......“程序文件”。如果没有空格没有问题,您可以包含它们,但它们如果在使用命令提示符时有空格,则为必填项。
这将生成几个文件,但它是我们感兴趣的 DLL。这就是 System.loadLirbary() java 方法要查找的内容。
8)恭喜!你在最后一步。只需获取 DLL 程序集并将其粘贴到以下位置:
<path_of_NetBeansProjects_folder>/<project_name>/<module_name>/build/cluster/modules/lib/x64
请注意,您可能必须创建“lib”和“x64”文件夹。
Example:
C:\Users\<user_name>\Documents\NetBeansProjects\<application_name>\<module_name>\build\cluster\modules\lib\x64\NativeInterfaceTest.dll
Java 代码...注意我们如何在 loadLibrary() 调用中不包含“.dll”文件扩展名?
System.loadLibrary( "/x64/NativeInterfaceTest" );
现在,在您的 Java 代码中,您可以创建一个 NativeInterfaceTest 对象并调用 echoString() 方法,它将返回您在 NativeInterfaceTest.c 源代码文件中键入的字符串值。
希望这可以为您节省我在自己试图解决所有这些问题时所遭受的脑损伤。祝你好运,编码愉快!