// 
//     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。



image::images/netbeans-stamp-80-74.png[title="此页上的内容适用于 NetBeans IDE 7.4 和 8.0"]

|===
|- |<<requirements,要求>> 

|- |<<modules, 为教程设置环境>> 

|- |<<javaproject,设置 Java 应用程序项目>> 

|- |<<c-library, 设置新的 C/C++ 动态库项目>> 

|- |<<running,构建和运行应用程序>> 

|- |<<next,后续步骤>> 
|===


== 要求

*要学习本教程，您需要具备以下软件和资源。*

|===
|软件或资源 |要求的版本 

|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[]
2. 在 "Project Name"（项目名称）字段中，键入  ``JNIDemoJava`` 。
3. 您可以将 "Project Location"（项目位置）更改为计算机上的任何目录，但在这里，我们使用用户目录中默认的 NetBeansProjects。
4. 让 "Create Main Class"（创建主类）复选框保持选中状态，然后将主类名更改为  ``jnidemojava.Main`` 。

image::images/jni-new-java-app.png[]
5. 单击 "Finish"（完成）。

IDE 将创建  ``NetBeansProjects/JNIDemoJava``  项目文件夹。


=== 编辑主类源代码

1. 要在编辑器中打开主类源代码，请右键单击  ``Main.java``  类节点，然后选择 "Open"（打开）。
2. 将  ``main``  方法中的  ``//TODO code application logic here``  一行替换为以下内容：

[source,java]
----

new Main().nativePrint();
----
3. 请注意左旁注中显示错误和灯泡的指示符。单击该指示符，系统将会提示您一个快捷键，用于创建方法  ``nativePrint`` 。
4. 单击此快捷键，IDE 将会插入以下代码：

[source,java]
----

private void nativePrint() {
      throw new UnsupportedOperationException("Not supported yet");
   }
----
5. 删除以下行

[source,java]
----

throw new UnsupportedOperationException("Not supported yet");
----
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();
}
----
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 部分时需要用到它。

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[]
2. 在 "Project Name"（项目名称）字段中，键入  ``JNIDemoCdl`` 。
3. 在 "Project Location"（项目位置）字段中，使用 Java 应用程序项目所用的相同位置，即  ``NetBeansProjects`` 。该位置应显示为默认值。
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``  库的引用时需要这些设置。

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 相关的问题。

8. 单击左面板中的 "Linker"（链接器）类别。
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[]
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");

}

----
3. 保存  ``JNIDemo.c``  文件。
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`` 
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[+发送有关此教程的反馈意见+]
