2.2 JNI与C ++
对于上面的例子,我们可以使用C ++程序(称为HelloJNI.cpp
)代替C程序。
#include <jni.h>
#include <iostream>
#include "HelloJNI.h"
using namespace std;
// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
cout << "Hello World from C++!" << endl;
return;
}
将C ++程序编译到共享库中,如下所示:
(Windows)64位JDK
在Cygwin上,您需要安装mingw64-x86-gcc-g++
包。
> x86_64-w64-mingw32-g ++ -I“%JAVA_HOME%\ include”-I“%JAVA_HOME%\ include \ win32”-shared -o hello.dll HelloJNI.cpp
(Ubuntu)64位JDK
$ g ++ -fPIC -I“$ JAVA_HOME / include”-I“$ JAVA_HOME / include / linux”-shared -o libhello.so HelloJNI.cpp
运行Java程序
> java HelloJNI
or
> java -Djava.library.path=. HelloJNI
注意 :如果遇到“ java.lang.UnsatisfiedLinkError: hello.dll: Can't find dependent libraries
”,则需要找到DLL依赖性walker来跟踪依赖库。 搜索库(在Cygwin下)并在PATH
包含库。 在我的例子中,依赖库是“ libstdc++-6.dll
”,位于“ cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin
”。
2.3 JNI与C / C ++混合物
步骤1:编写使用本机代码的Java类 - HelloJNICpp.java
public class HelloJNICpp {
static {
System.loadLibrary("hello"); // hello.dll (Windows) or libhello.so (Unixes)
}
// Native method declaration
private native void sayHello();
// Test Driver
public static void main(String[] args) {
new HelloJNICpp().sayHello(); // Invoke native method
}
}
第2步:编译Java程序并生成C / C ++头文件HelloJNICpp.h
javac -h . HelloJNICpp
生成的头文件“ HelloJNICpp.h
”将本机函数声明为:
JNIEXPORT void JNICALL Java_HelloJNICpp_sayHello (JNIEnv *,jobject);
第3步:C / C ++实现 - HelloJNICppImpl.h , HelloJNICppImpl.cpp和HelloJNICpp.c
我们将用C ++实现该程序(在“ HelloJNICppImpl.h
”和“ HelloJNICppImpl.cpp
”中),但是使用C程序(“ HelloJNICpp.c
”)与Java接口。
C ++头文件- “ HelloJNICppImpl.h
”
#ifndef _HELLO_JNI_CPP_IMPL_H
#define _HELLO_JNI_CPP_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
void sayHello ();
#ifdef __cplusplus
}
#endif
#endif
C ++实现 - “ HelloJNICppImpl.cpp
”
#include "HelloJNICppImpl.h"
#include <iostream>
using namespace std;
void sayHello () {
cout << "Hello World from C++!" << endl;
return;
}
C程序与Java连接 - “ HelloJNICpp.c
”
#include <jni.h>
#include "HelloJNICpp.h"
#include "HelloJNICppImpl.h"
JNIEXPORT void JNICALL Java_HelloJNICpp_sayHello (JNIEnv *env, jobject thisObj) {
sayHello(); // invoke C++ function
return;
}
将C / C ++程序编译为共享库(Windows的“ hello.dll
”)。
(Windows)64位JDK
在Cygwin上,您需要安装mingw64-x86-gcc-g++
包。
> x86_64-w64-mingw32-g ++ -I“%JAVA_HOME%\ include”-I“%JAVA_HOME%\ include \ win32”-shared -o hello.dll HelloJNICpp.c HelloJNICppImpl.cpp
(Ubuntu)64位JDK
$ g ++ -fPIC -I“$ JAVA_HOME / include”-I“$ JAVA_HOME / include / linux”-shared -o libhello.so HelloJNICpp.c HelloJNICppImpl.cpp
第4步:运行Java程序
> java HelloJNICpp
or
> java -Djava.library.path=. HelloJNICpp
注意 :如果遇到“ java.lang.UnsatisfiedLinkError: hello.dll: Can't find dependent libraries
”,则需要找到DLL依赖性walker来跟踪依赖库。 搜索库(在Cygwin下)并在PATH
包含库。 在我的例子中,依赖库是“ libstdc++-6.dll
”,位于“ cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin
”。
2.4 JNI in Package
对于生产,所有Java类都应保存在适当的包中,而不是默认的无名包。
第1步:JNI程序 - myjni \ HelloJNI.java
package myjni;
public class HelloJNI {
static {
System.loadLibrary("hello"); // hello.dll (Windows) or libhello.so (Unixes)
}
// A native method that receives nothing and returns void
private native void sayHello();
public static void main(String[] args) {
new myjni.HelloJNI().sayHello(); // invoke the native method
}
}
这个JNI类保存在“ myjni
”包中 - 保存为“ myjni\HelloJNI.java
”。
第2步:编译JNI程序并生成C / C ++标头
// change directory to package base directory
> javac -h include myjni\HelloJNI
编译输出是“ myjni\HelloJNI.class
”。
在此示例中,我们决定将头文件放在“ include
”子目录下。 生成的输出是“ include\myjni_HelloJNI.h
”。
头文件声明了一个本机函数:
JNIEXPORT void JNICALL Java_myjni_HelloJNI_sayHello (JNIEnv *,jobject);
记下本机函数命名约定: Java_< fully-qualified-name >_methodName
,用下划线替换点。
第3步:C实现 - HelloJNI.c
#include <jni.h>
#include <stdio.h>
#include "include\myjni_HelloJNI.h"
JNIEXPORT void JNICALL Java_myjni_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
printf("Hello World!\n");
return;
}
编译C程序:
//用于Windows 64位JDK > x86_64-w64-mingw32-gcc -I“%JAVA_HOME%\ include”-I“%JAVA_HOME%\ include \ win32”-shared -o hello.dll HelloJNI.c
您现在可以运行JNI程序:
> java -Djava.library.path =。 myjni.HelloJNI