public class JNIT { static { System.loadLibrary("JNIT"); } public static native String hello(String msg); public static void main(String[] args) { String str= hello("Hello, c++!" ); System.out.print("java get c++ Str:"+str); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class JNIT */ #ifndef _Included_JNIT #define _Included_JNIT #ifdef __cplusplus extern "C" { #endif /* * Class: JNIT * Method: hello * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_JNIT_hello (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
注:
文件中的 Java_JNIT_hello 说明是Java中的JNIT类的hello方法
文件中的 #include<jni.h>等 <> 符号在命令行打包动态库时会打包失败 须要改成 “jni.h”java
生成的文件中须要导入的jni.h 和 jni_md.h 在JAVAHOME/jdk/include和 JAVAHOME/jdk/include/win32 目录下,你能够选择直接拷贝或后期配置添加(注意32和64位区分)linux
// dllmain.cpp : 定义 DLL 应用程序的入口点。 // pch.cpp: 与预编译标头对应的源文件 #include "JNIT.h" // 当使用预编译的头时,须要使用此源文件,编译才能成功。 #include <iostream> using namespace std; JNIEXPORT jstring JNICALL Java_JNIT_hello (JNIEnv * jEnv, jclass jcls, jstring jstr) { const char *c_str = NULL; char buff[128] = { 0 }; c_str = (jEnv)->GetStringUTFChars(jstr,false); if (c_str == NULL) { printf("out of memory.\n"); } cout << "c++ get Java Str: "<< c_str << endl; // (jEnv)->ReleaseStringUTFChars( jstr, c_str); //printf("c++ get Java Str:%s\n", c_str); return (jEnv)->NewStringUTF("hello java"); }
这里gcc的环境有32位与64位的区分 否则运行会有错误Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\eclipsejee\workspace\JNIT\src\JNIT.dll: Can't load IA 32-bit .dll on a AMD 64-bit platformios
cl -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -LD HelloWorld.c -FeHelloWorld.dll 参数选项说明: -I :和 mac os x 同样,包含编译 JNI 必要的头文件 -LD:标识将指定的文件编译成动态连接库 -Fe:指定编译后生成的动态连接库的路径及文件名
(1)新建dll项目c++
(2)将写好的JNIT.cpp粘贴内容粘贴到 dllMain.cpp 中 这里能够对dllMain.cpp 修更名称,将JNIT.h粘贴进项目目录。app
(3)右键项目》属性》c/c++》常规》附加包含目录,将jdk/include和jdk/include/win32添加进去,从而引入jni.h和jni_md.heclipse
(4)去除编译器默认对pch文件的预编译,右键项目》属性》c/c++》预编译头》预编译头》不使用预编译头函数
(5)运行项目,会在控制台输出dll文件路径测试
g++ -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -Wl,–kill-at -s -o lib.dll JNIT.cpp 解释一下: -I(大写字母I,include的意思)是加入本身的库,也就是告诉编译器jni.h的位置。固然不加这个参数也能够,本身把jni.h和jni_md.h文件复制出来和Test.c放一块儿,另外include改成”” -shared表示编译成.dll库文件 -s参数能够大幅减少.dll文件的大小,不加也能够 -o表示目标文件名,不加也能够,会有默认名,但要本身改为java中导入库的名字,这里是lib -Wl,–kill-at 防止编译后的函数名被自动加上@符号,并取消警告。(是小写字母L,不是数字1)
当你把jni.h 和jni_md.h 粘贴到当前目录下可使用如下命令
g++ -shared -Wl,-kill-at -s -o lib.dll JNIT.cpp
g++ -s -o JNIT.dll JNIT.cpp
g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared -o JNIT.so 参数说明: -I: 包含编译JNI必要的头文件 -fPIC: 编译成与位置无关的独立代码 -shared:编译成动态库 -o: 指定编译后动态库生成的路径和文件名
当你把jni.h 和jni_md.h 粘贴到当前目录下可使用如下命令
g++ -shared -Wl,-kill-at -s -o lib.dll JNIT.cpp
g++ JNIT.cpp -fPIC -shared -o JNIT.so
java JNIT