NetBeans Development 7 - Windows 7 64 位……JNI 原生调用……一个如何指导 [英] NetBeans Development 7 - Windows 7 64-bit … JNI native calls ... a how to guide

查看:19
本文介绍了NetBeans Development 7 - Windows 7 64 位……JNI 原生调用……一个如何指导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为您提供此内容,希望可以为您节省一些时间和痛苦.

I provide this for you to hopefully save you some time and pain.

作为我在 Windows 64 位工作站上了解 NB Development v7 的经验的一部分,我发现了另一个令人沮丧的冒险,试图让 JNI(Java 本机接口)功能启动并在我的项目中工作.因此,我包含了所需步骤的简要摘要(因为我发现的所有文档对于这些版本的 Windows 和 NetBeans 都是完全不正确的,关于如何执行 JNI).我花了几天的时间进行实验并查看我能找到的包含这些技术作为关键字搜索的每个网页.哎哟!!不好玩.

As part of my experience in getting to know NB Development v7 on my Windows 64-bit workstation I found another frustrating adventure in trying to get the JNI (Java Native Interface) abilities up and working in my project. As such, I am including a brief summary of steps required (as all the documentation I found was completely incorrect for these versions of Windows and NetBeans on how to do JNI). It took a couple of days of experimentation and reviewing every webpage I could find that included these technologies as keyword searches. Yuk!! Not fun.

首先,由于 NetBeans 开发是所有关于模块的",如果您正在阅读本文,您可能需要一个或多个模块来执行 JNI 调用.本站点或 Internet 上提供的大部分内容(更不用说 NB7 中的帮助文件)对于这些版本来说要么是完全错误的,要么非常稀少,以至于对 JNI 专家以外的任何人都没有用处.

To begin, as NetBeans Development is "all about modules" if you are reading this you probably have a need for one, or more, of your modules to perform JNI calls. Most of what is available on this site or the Internet in general (not to mention the help file in NB7) is either completely wrong for these versions, or so sparse as to be essentially unuseful to anyone other than a JNI expert.

这就是您正在寻找的内容......切入正题"-如何指导"以获取 JNI 调用并在您的 NB7/Windows 64 位机器上工作.

Here is what you are looking for ... the "cut to the chase" - "how to guide" to get a JNI call up and working on your NB7 / Windows 64-bit box.

1) 在您的 NetBeans 模块(而不是主机应用程序)中声明您的本机方法,并确保您可以无错误地编译 Java 源代码.

1) From within your NetBeans Module (not the host application) declare your native method(s) and make sure you can compile the Java source without errors.

示例:

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 代码中调用.

Take notice to the fact that we only load the Assembly once (as it's in a static block), because otherwise you will throw exceptions if attempting to load it again. Also take note of our single (in this example) native method titled "echoString". This is the method that our C / C++ application is going to implement, then via the majic of JNI we'll call from our Java code.

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

2) If using a 64-bit version of Windows (which we are here) we need to open a 64-bit Visual Studio Command Prompt (versus the standard 32-bit version), and execute the "vcvarsall" BAT file, along with an "amd64" command line argument, to set the environment up for 64-bit tools.

示例:

<path_to_Microsoft_Visual_Studio_10.0>/VC/vcvarsall.bat amd64

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

Take note that you can use any version of the C / C++ compiler from Microsoft you wish. I happen to have Visual Studio 2005, 2008, and 2010 installed on my box so I chose to use "v10.0" but any that support 64-bit development will work fine. The other important aspect here is the "amd64" param.

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

3) In the Command Prompt change drives directories on your computer so that you are at the root of the fully qualified Class location on the file system that contains your native method declaration.

示例:我本机声明的方法的完全限定类名称是org.mycompanyname.nativelogic.NativeInterfaceTest".由于我们在上面的步骤 1 中成功编译了 Java,我们应该会发现它包含在我们的 NetBeans 模块中,类似于以下内容:

Example: The fully qualified class name for my natively declared method is "org.mycompanyname.nativelogic.NativeInterfaceTest". As we successfully compiled our Java in Step 1 above, we should find it contained in our NetBeans Module something similar to the following:

"/build/classes/org/mycompanyname/nativelogic/NativeInterfaceTest.class"

"/build/classes/org/mycompanyname/nativelogic/NativeInterfaceTest.class"

为了下一步,我们需要确保我们的命令提示符直接设置为当前的/build/classes".

We need to make sure our Command Prompt sets, as the current directly, "/build/classes" because of our next step.

4) 在这一步中,我们将创建包含 JNI 所需语句的 C/C++ 头文件.在命令提示符中键入以下内容:

4) In this step we'll create our C / C++ Header file that contains the JNI required statements. Type the following in the Command Prompt:

javah -jni org.mycompanyname.nativelogic.NativeInterfaceTest 并按回车键.如果您收到任何类型的错误,指出这是一个无法识别的命令,这仅意味着您的 Windows 计算机不知道该命令的 PATH(它在您的/bin 文件夹中).从那里运行命令,或者在调用此应用程序时包含完全限定的路径名​​,或者将计算机的 PATH 环境变量设置为在搜索中包含该路径.

javah -jni org.mycompanyname.nativelogic.NativeInterfaceTest and hit enter. If you receive any kind of error that states this is an unrecognized command that simply means your Windows computer does not know the PATH to that command (it's in your /bin folder). Either run the command from there, or include the fully qualified path name when invoking this application, or set your computer's PATH environmental variable to include that path in its search.

这应该会生成一个名为org_mycompanyname_nativelogic_NativeInterfaceTest.h"的文件……一个 C 头文件.如果您以后需要备份,我会制作一份副本.

This should produce a file called "org_mycompanyname_nativelogic_NativeInterfaceTest.h" ... a C Header file. I'd make a copy of this in case you need a backup later.

5) 编辑 NativeInterfaceTest.h 头文件并包含 echoString() 方法的实现.

5) Edit the NativeInterfaceTest.h header file and include an implementation for the echoString() method.

示例:

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 目的创建它们.

Notice how you can't simply return a normal Java String (because you're in C at the moment). You have to tell the passed in JVM variable to create a Java String for you that will be returned back. Check out the following Oracle web page for other data types and how to create them for JNI purposes.

6) 关闭并保存对头文件的更改.既然您已经向 Header 添加了一个实现,请将文件扩展名从.h"更改为.c",因为它现在是一个正确实现 JNI 所需接口的 C 源代码文件.

6) Close and Save your changes to the Header file. Now that you've added an implementation to the Header change the file extension from ".h" to ".c" as it's now a C source code file that properly implements the JNI required interface.

示例:NativeInterfaceTest.c

Example: NativeInterfaceTest.c

7) 我们需要编译新创建的源代码文件并链接它.在命令提示符中键入以下内容:

7) We need to compile the newly created source code file and Link it too. From within the Command Prompt type the following:

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"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"文件夹路径周围的引号是必需的,因为我的文件夹名称中有空格......程序文件".如果没有空格,您可以将它们包含在内,没有问题,但如果您在使用命令提示符时有空格,则它们是必需的.

Notice the quotes around the paths to the 'include" and 'include/win32' folders is required because I have spaces in my folder names ... 'Program Files'. You can include them if you have no spaces without problems, but they are mandatory if you have spaces when using a command prompt.

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

This will generate several files, but it's the DLL we're interested in. This is what the System.loadLirbary() java method is looking for.

8) 恭喜!你在最后一步.只需将 DLL 程序集粘贴到以下位置即可:

8) Congratuations! You're at the last step. Simply take the DLL Assembly and paste it at the following location:

<path_of_NetBeansProjects_folder>/<project_name>/<module_name>/build/cluster/modules/lib/x64

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

Note that you'll probably have to create the "lib" and "x64" folders.

Example:
C:Users<user_name>DocumentsNetBeansProjects<application_name><module_name>uildclustermoduleslibx64NativeInterfaceTest.dll

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

Java code ... notice how we don't inlude the ".dll" file extension in the loadLibrary() call?

System.loadLibrary( "/x64/NativeInterfaceTest" );

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

Now, in your Java code you can create a NativeInterfaceTest object and call the echoString() method and it will return the String value you typed in the NativeInterfaceTest.c source code file.

希望这可以避免我试图自己解决所有这些问题时所遭受的脑损伤.祝你好运,编码愉快!

Hopefully this will save you the brain damage I endured trying to figure all this out on my own. Good luck and happy coding!

推荐答案

既然这个问题不是问题而是howto,我的回答不是答案而是howIdo:

Since this question is not a question but a howto, my answer is not an answer but a howIdo:

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

Your 32/64 technique requires seperate directories for the DLLs.

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

这是怎么做的:

String archDataModel = System.getProperty("sun.arch.data.model");
System.loadLibrary("dllName" + archDataModel);

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

which allows dllName32.dll and dllName64.dll to be packaged in the same directory.

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

...Just another man's opinion.

这篇关于NetBeans Development 7 - Windows 7 64 位……JNI 原生调用……一个如何指导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆