NetBeans开发7 - Windows 7 64位... JNI本机调用...如何引导

Bon*_*ver 5 64-bit java-native-interface windows-7 netbeans-7

我为你提供这个,希望能为你节省一些时间和痛苦.

作为我在Windows 64位工作站上了解NB Development v7的经验的一部分,我发现了另一个令人沮丧的冒险尝试获得JNI(Java Native Interface)功能并在我的项目中工作.因此,我将简要介绍所需的步骤(因为我发现所有文档对于这些版本的Windows和NetBeans完全不正确,如何进行JNI).我花了几天的时间进行实验,并查看了我能找到的每个网页,其中包括这些技术作为关键字搜索.育!不好玩.

首先,由于NetBeans开发是"所有关于模块",如果您正在阅读本文,您可能需要一个或多个模块来执行JNI调用.一般来说,本网站或互联网上提供的大部分内容(更不用说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);
    }
Run Code Online (Sandbox Code Playgroud)

请注意我们只加载一次Assembly(因为它在静态块中),因为否则如果再次尝试加载它会抛出异常.另请注意我们的单个(在此示例中)标题为"echoString"的本机方法.这是我们的C/C++应用程序要实现的方法,然后通过我们将从Java代码调用的JNI的majic.

2)如果使用64位版本的Windows(我们在这里),我们需要打开64位Visual Studio命令提示符(与标准的32位版本相比),并执行"vcvarsall"BAT文件,以及一个"amd64"命令行参数,用于为64位工具设置环境.

例:

<path_to_Microsoft_Visual_Studio_10.0>/VC/vcvarsall.bat amd64
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用Microsoft希望的任何版本的C/C++编译器.我碰巧在我的盒子上安装了Visual Studio 2005,2008和2010,所以我选择使用"v10.0",但任何支持64位开发的都可以正常工作.这里另一个重要方面是"amd64"参数.

3)在命令提示符下更改计算机上的drives \目录,以便您位于包含本机方法声明的文件系统上的完全限定类位置的根目录.

示例:我本机声明的方法的完全限定类名是"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并按Enter键.如果您收到任何类型的错误,指出这是一个无法识别的命令,只是意味着您的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"));
}
Run Code Online (Sandbox Code Playgroud)

注意你怎么不能简单地返回一个普通的Java String(因为你现在在C中).您必须告诉传入的JVM变量为您创建一个将返回的Java字符串.查看以下Oracle Web页面了解其他数据类型以及如何为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
Run Code Online (Sandbox Code Playgroud)

请注意,'include'和'include/win32'文件夹的路径周围的引号是必需的,因为我的文件夹名称中有空格...'Program Files'.如果没有空格没有问题,可以包含它们,但是如果在使用命令提示符时有空格,则是必需的.

这将生成几个文件,但它是我们感兴趣的DLL.这是System.loadLirbary()java方法正在寻找的.

8)祝贺!你是最后一步.只需获取DLL程序集并将其粘贴到以下位置:

<path_of_NetBeansProjects_folder>/<project_name>/<module_name>/build/cluster/modules/lib/x64
Run Code Online (Sandbox Code Playgroud)

请注意,您可能必须创建"lib"和"x64"文件夹.

Example:
C:\Users\<user_name>\Documents\NetBeansProjects\<application_name>\<module_name>\build\cluster\modules\lib\x64\NativeInterfaceTest.dll
Run Code Online (Sandbox Code Playgroud)

Java代码...请注意我们如何在loadLibrary()调用中包含".dll"文件扩展名?

System.loadLibrary( "/x64/NativeInterfaceTest" );
Run Code Online (Sandbox Code Playgroud)

现在,在Java代码中,您可以创建一个NativeInterfaceTest对象并调用echoString()方法,它将返回您在NativeInterfaceTest.c源代码文件中键入的String值.

希望这可以为你节省大脑伤害,我忍受试图自己解决这一切.祝你好运,编码愉快!

Jav*_*a42 2

由于这个问题不是一个问题而是一个howto,所以我的答案不是一个答案而是一个howIdo:

您的 32/64 技术需要单独的 DLL 目录。

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
Run Code Online (Sandbox Code Playgroud)

这就是我的做法:

String archDataModel = System.getProperty("sun.arch.data.model");
System.loadLibrary("dllName" + archDataModel);
Run Code Online (Sandbox Code Playgroud)

它允许 dllName32.dll 和 dllName64.dll 打包在同一目录中。

...只是另一个人的意见。