| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = 在 Linux 上使用 NetBeans IDE 和 C/C++ 插件开始开发 JNI |
| :jbake-type: tutorial |
| :jbake-tags: tutorials |
| :jbake-status: published |
| :icons: font |
| :syntax: true |
| :source-highlighter: pygments |
| :toc: left |
| :toc-title: |
| :description: 在 Linux 上使用 NetBeans IDE 和 C/C++ 插件开始开发 JNI - Apache NetBeans |
| :keywords: Apache NetBeans, Tutorials, 在 Linux 上使用 NetBeans IDE 和 C/C++ 插件开始开发 JNI |
| |
| _2014 年 3 月_ [修订版本号:V8.0-1] |
| |
| 本教程将指导您如何创建使用 Java^TM^ 本机接口 (JNI) 代码(采用 C 编程语言编写)的简单应用程序。 |
| |
| 本教程特定于 Linux。 |
| |
| |
| == 要求 |
| |
| *要学习本教程,您需要具备以下软件和资源。* |
| |
| |=== |
| |软件或资源 |要求的版本 |
| |
| |NetBeans IDE |link:https://netbeans.org/downloads/index.html[+带有 NetBeans C/C++ 插件的版本 7.4 或 8.0+] |
| |
| |Java 开发者工具包 (JDK) |link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+版本 7 或 8+] |
| |
| |C 和 C++ 编译器、 ``make`` 、 ``gdb`` |link:../../../community/releases/80/cpp-setup-instructions.html[+ 配置 NetBeans IDE 以使用 C/C++/Fortran+] |
| |=== |
| |
| 有关下载并安装必需软件的信息,请参见 link:../../../community/releases/80/install.html[+NetBeans IDE 8.0 安装说明+]和link:../../../community/releases/80/cpp-setup-instructions.html[+配置 NetBeans IDE 以使用 C/C++/Fortran+]。 |
| |
| |
| == 为教程设置环境 |
| |
| 本教程需要使用 Java 模块和 C/C++ 模块。如果您已下载 NetBeans IDE C/C++ 包,则可以单独下载其他 Java 模块。 |
| |
| 要确定是否拥有 Java 和 C/C++ 模块,请选择 "File"(文件)> "New Project"(新建项目)。项目类别应该包括 Java 和 C/C++。 |
| |
| *下载可能缺少的 Java 和 C/C++ 模块:* |
| |
| 1. 在 NetBeans IDE 中,选择 "Tools"(工具)> "Plugins"(插件)。 |
| 2. 在 "Available Plugins"(可用插件)标签中选中 Java 或 C/C++ 的复选框,具体取决于您的 IDE 中缺少哪个模块。如果您已拥有插件,则 "Installed"(已安装)标签中将会列出这些插件。 |
| 3. 单击 "Install"(安装)。 |
| 4. 在 "NetBeans IDE Installer"(NetBeans IDE 安装程序)对话框中,单击 "Next"(下一步),接受许可证条款复选框,然后单击 "Install"(安装)。 |
| 5. 安装完成之后,单击 "Finish"(完成)。 |
| |
| |
| == 设置 Java 应用程序项目 |
| |
| 本课程中需要用到 Java 项目和 C 项目。在本部分中,将为要开发的 JNI 应用程序创建并配置 Java 项目。此外,还将创建新的 Java 应用程序项目,初始化其主类,并向此类中添加本机方法。 |
| |
| 1. 选择 "File"(文件)> "New Project"(新建项目)。选择 "Java" 类别和 "Java Application"(Java 应用程序)项目类型。单击 "Next"(下一步)。 |
| image::images/jni-new-project-java.png[] |
| |
| [start=2] |
| . 在 "Project Name"(项目名称)字段中,键入 ``JNIDemoJava`` 。 |
| |
| [start=3] |
| . 您可以将 "Project Location"(项目位置)更改为计算机上的任何目录,但在这里,我们使用用户目录中默认的 NetBeansProjects。 |
| |
| [start=4] |
| . 让 "Create Main Class"(创建主类)复选框保持选中状态,然后将主类名更改为 ``jnidemojava.Main`` 。 |
| |
| image::images/jni-new-java-app.png[] |
| |
| [start=5] |
| . 单击 "Finish"(完成)。 |
| |
| IDE 将创建 ``NetBeansProjects/JNIDemoJava`` 项目文件夹。 |
| |
| |
| === 编辑主类源代码 |
| |
| 1. 要在编辑器中打开主类源代码,请右键单击 ``Main.java`` 类节点,然后选择 "Open"(打开)。 |
| 2. 将 ``main`` 方法中的 ``//TODO code application logic here`` 一行替换为以下内容: |
| |
| [source,java] |
| ---- |
| |
| new Main().nativePrint(); |
| ---- |
| |
| [start=3] |
| . 请注意左旁注中显示错误和灯泡的指示符。单击该指示符,系统将会提示您一个快捷键,用于创建方法 ``nativePrint`` 。 |
| |
| [start=4] |
| . 单击此快捷键,IDE 将会插入以下代码: |
| |
| [source,java] |
| ---- |
| |
| private void nativePrint() { |
| throw new UnsupportedOperationException("Not supported yet"); |
| } |
| ---- |
| |
| [start=5] |
| . 删除以下行 |
| |
| [source,java] |
| ---- |
| |
| throw new UnsupportedOperationException("Not supported yet"); |
| ---- |
| |
| [start=6] |
| . 通过将 ``native`` 关键字插入方法签名中来修改 ``nativePrint()`` 方法,使其现在看起来如下所示: |
| |
| [source,java] |
| ---- |
| |
| private native void nativePrint(); |
| ---- |
| |
| ``native`` 关键字表示该方法的实现位于外部本机库中。但在运行时,该库的位置并不明确。 |
| |
| 新的主方法看起来应如下所示: |
| |
| |
| [source,java] |
| ---- |
| |
| public static void main(String[] args) { |
| new Main().nativePrint(); |
| } |
| |
| private native void nativePrint(); |
| } |
| ---- |
| |
| [start=7] |
| . 右键单击项目名称,然后选择 "Clean and Build"(清理并构建)。项目应该成功构建。 |
| |
| |
| === 创建本机库头文件 |
| |
| 在本部分中,我们将使用 ``javah`` ,这是一种用于从 Java 类创建 C 头文件的 Java 工具。 |
| |
| 1. 在终端窗口中,导航至 ``NetBeansProjects`` 目录。 |
| 2. 键入以下命令: |
| |
| [source,java] |
| ---- |
| |
| javah -o JNIDemoJava.h -classpath JNIDemoJava/build/classes jnidemojava.Main |
| |
| ---- |
| |
| ``JNIDemoJava.h`` C 头文件是在 NetBeansProjects 目录中生成的。需要此文件才能为 ``nativePrint()`` 方法的本机实现提供正确的函数声明。您在以后创建此应用程序的 C 部分时需要用到它。 |
| |
| |
| [start=3] |
| . 切换回 NetBeans IDE 窗口。 |
| |
| *小结* |
| |
| 在本练习中,创建了新的 Java 应用程序项目,指定了其位置,并定义了该项目中主类的包和名称。此外,还向主类中添加了新方法,并将其标记为具有本机实现的方法。最后,创建了 C 头文件,它在稍后编译本机库时需要用到。 |
| |
| |
| == 设置新的 C/C++ 动态库项目 |
| |
| 本部分向您说明了如何创建应用程序的本机部分。您将创建 C++ 动态库项目,并对其进行配置,使之能够构建 JNI 代码。 |
| |
| 设置了项目后,您将为先前在应用程序的 Java 部分中声明的本机方法创建实现。 |
| |
| 1. 选择 "File"(文件)> "New Project"(新建项目)。在 "Categories"(类别)下,选择 "C/C++"。在 "Projects"(项目)下,选择 "C/C++ Dynamic Library"(C/C++ 动态库)。单击 "Next"(下一步)。 |
| image::images/jni-new-project-c.png[] |
| |
| [start=2] |
| . 在 "Project Name"(项目名称)字段中,键入 ``JNIDemoCdl`` 。 |
| |
| [start=3] |
| . 在 "Project Location"(项目位置)字段中,使用 Java 应用程序项目所用的相同位置,即 ``NetBeansProjects`` 。该位置应显示为默认值。 |
| |
| [start=4] |
| . 接受所有其他字段的默认值,然后单击 "Finish"(完成)。 |
| |
| IDE 将创建 ``NetBeansProjects/JNIDemoCdl`` 项目文件夹。 |
| |
| |
| === 设置项目属性 |
| |
| 1. 右键单击 "JNIDemoCdl" 项目节点,然后选择 "Properties"(属性)。 |
| 2. 在 "Properties"(属性)对话框中,选择 "Build"(构建)属性下方的 "C Compiler"(C 编译器)节点。 |
| 3. 单击 "Include Directories and Headers..."(包含目录和头文件...)按钮,然后在 "Include Directories and Headers"(包含目录和头文件)对话框中单击 "Add"(添加)。 |
| 4. 浏览到 JDK 目录,然后选择 ``include`` 子目录。 |
| 5. 选择 "Store path as Absolute"(存储为绝对路径)选项,然后单击 "Select"(选择),将此目录添加到此项目的 "Include Directories"(包括目录)中。 |
| 6. 以同样的方式添加 JDK 的 ``include/linux`` 目录,然后单击 "OK"(确定)。 |
| image::images/jni-include-directories.png[] |
| |
| 从 C 代码中启用对 Java ``jni.h`` 库的引用时需要这些设置。 |
| |
| |
| [start=7] |
| . 找到 "C Compiler"(C 编译器)选项的 "Compilation Line"(编译行)区域。单击 "Additional Options"(其他选项)属性的文本字段,然后键入 ``-shared -m32`` 。image::images/jni-project-properties-cmd-options.png[] |
| |
| ``-shared`` 选项用于通知编译器生成动态库。 |
| ``-m32`` 选项用于通知编译器创建 32 位二进制文件。默认情况下,在 64 位系统上,已编译二进制文件是 64 位的,这会导致很多与 32 位 JDK 相关的问题。 |
| |
| |
| [start=8] |
| . 单击左面板中的 "Linker"(链接器)类别。 |
| |
| [start=9] |
| . 单击 "Output"(输出)文本字段,然后将字符串 |
| |
| [source,java] |
| ---- |
| |
| ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libJNIDemoCdl.so |
| ---- |
| 替换为字符串 |
| |
| [source,java] |
| ---- |
| |
| dist/libJNIDemoCdl.so |
| ---- |
| 以简化生成的共享对象文件的路径。这将简化从 Java 引用文件的过程。 |
| image::images/jni-project-properties-linker.png[] |
| |
| [start=10] |
| . 单击 "OK"(确定)。此时将保存已定义的设置。 |
| |
| |
| === 添加头文件 |
| |
| 1. 转至终端窗口,然后将以前生成的 ``JNIDemoJava.h`` 头文件从 ``NetBeansProjects`` 目录移至 C/C++ 库项目目录,即 ``NetBeansProjects/JNIDemoCdl`` 。 |
| 2. |
| 在 "Projects"(项目)窗口中,右键单击 ``JNIDemoCdl`` 项目的 "Header Files"(头文件)节点,然后选择 "Add Existing Item"(添加现有项)。导航到 ``NetBeansProjects/JNIDemoCdl`` 目录并选择 ``JNIDemoJava.h`` 文件,然后单击 "Select"(选择)。 |
| |
| ``JNIDemoJava.h`` 文件显示在 "Header Files"(头文件)的下方。 |
| |
| image::images/jni-source-files-include-file.png[] |
| |
| |
| === 实现方法 |
| |
| 1. 右键单击 ``JNIDemoCdl`` 项目的“源文件”节点,然后选择 "New"(新建)> "C Source File"(C 源文件)。在 "File Name"(文件名)字段中,键入 ``JNIDemo`` ,然后单击 "Finish"(完成)。编辑器将打开 ``JNIDemo.c`` 文件。 |
| 2. 键入以下代码,以编辑 ``JNIDemo.c`` 文件: |
| |
| [source,c] |
| ---- |
| |
| #include <jni.h> |
| #include <stdio.h> |
| #include "JNIDemoJava.h" |
| |
| JNIEXPORT void JNICALL Java_jnidemojava_Main_nativePrint |
| (JNIEnv *env, jobject obj) |
| { |
| |
| printf("\nHello World from C\n"); |
| |
| } |
| |
| ---- |
| |
| [start=3] |
| . 保存 ``JNIDemo.c`` 文件。 |
| |
| [start=4] |
| . 右键单击 ``JNIDemoCdl`` 项目节点,然后选择 "Build"(构建)。"Output"(输出)窗口将显示 ``BUILD SUCCESSFUL (total time 171ms)`` (构建成功(总时间为 171 毫秒))或类似内容。 |
| |
| *小结* |
| |
| 在本练习中,创建了新的 C/C++ 动态库,指定了其位置,并对其进行了配置,使之能够构建 Java 方法的 JNI 实现。此外,还为您在 Java 应用程序中声明的本机方法添加了已生成的头文件,并实现了它。 |
| |
| |
| == 构建和运行应用程序 |
| |
| 在本练习中,将对应用程序的 Java 部分执行一些最后的修改。为了确保 Java 部分正确加载您在上一个练习中编译的本机库,需要进行这些更改。然后,您将编译并运行生成的应用程序。 |
| |
| |
| === 配置 Java 项目 |
| |
| 1. 在编辑器中打开 ``Main.java`` 文件。 |
| 2. 使用上一个练习的缩写输出文件路径,在 ``public class Main`` 行之后为 C++ 动态库添加以下初始化代码: |
| |
| [source,java] |
| ---- |
| |
| static { |
| System.load("_full-path-to-NetBeansProjects-dir_/JNIDemoCdl/dist/libJNIDemoCdl.so"); |
| } |
| |
| ---- |
| 将 _full-path-to-NetBeansProjects-dir_ 替换为 NetBeansProjects 目录的路径,该路径应类似于 ``/home/_username_/NetBeansProjects`` |
| |
| [start=3] |
| . 保存 ``Main.java`` 文件。 |
| |
| |
| === 运行 JNIDemoJava 应用程序 |
| |
| 1. 在 "Projects"(项目)窗口中选择 JNIDemoJava 应用程序。 |
| 2. 按 F6 或单击工具栏中的 "Run"(运行)按钮,以运行应用程序。程序应正确执行,并且 "Output"(输出)窗口应显示类似以下内容的输出: |
| image::images/jni-build-success.png[] |
| |
| |
| === 小结 |
| |
| 在本练习中,执行了一些最后的配置步骤,并运行了应用程序,以验证本机方法的实现来自于本机 C 库。 |
| |
| |
| == 后续步骤 |
| |
| 如果要对照工作示例检查工作,则可以从 netbeans.org link:https://netbeans.org/projects/samples/downloads/download/Samples%252FCPlusPlus%252FJNIDemo.zip[+下载包含源代码的 zip 文件+]。 |
| |
| 您可以使用以下文档获取更多的信息: |
| |
| * link:quickstart.html[+C/C++ 项目快速入门教程+] |
| * link:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/[+JNI 规范+] |
| * link:http://en.wikipedia.org/wiki/Java_Native_Interface[+Java 本机接口+] |
| link:https://netbeans.org/about/contact_form.html?to=7&subject=Feedback:%20Beginning%20JNI%20with%20NetBeans%20IDE%20and%20C/C++%20Plugin%20on%20Linux[+发送有关此教程的反馈意见+] |