博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JNI学习
阅读量:6249 次
发布时间:2019-06-22

本文共 3423 字,大约阅读时间需要 11 分钟。

最近需要用到JNI,所以抽时间学习了下,对于我这个N年没用过C/C++的,从没用过VS2005的java码农来说,真不容易,编译个dll都遇到莫名其妙的问题~~

下面就来一步一步开始JNI之路。

一、通过java类得到.h头文件

首先,我们写一个java类,声明几个native方法

package jni.test;public class JNIWrapper {    public native void display();    public native double sum(double x, double y);        public native double divide(double x, double y);}

然后,依次执行如下命令,依次得到class和.h文件

编译class...\src>javac jni\test\JNIWrapper.java生成头文件...\src>javah jni.test.JNIWrapper

到这里就得到了一个名为“jni_test_JNIWrapper.h”的头文件,其内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include 
/* Header for class jni_test_JNIWrapper */#ifndef _Included_jni_test_JNIWrapper#define _Included_jni_test_JNIWrapper#ifdef __cplusplusextern "C" {#endif/* * Class: jni_test_JNIWrapper * Method: display * Signature: ()V */JNIEXPORT void JNICALL Java_jni_test_JNIWrapper_display (JNIEnv *, jobject);/* * Class: jni_test_JNIWrapper * Method: sum * Signature: (DD)D */JNIEXPORT jdouble JNICALL Java_jni_test_JNIWrapper_sum (JNIEnv *, jobject, jdouble, jdouble);/* * Class: jni_test_JNIWrapper * Method: divide * Signature: (DD)D */JNIEXPORT jdouble JNICALL Java_jni_test_JNIWrapper_divide (JNIEnv *, jobject, jdouble, jdouble);#ifdef __cplusplus}#endif#endif
jni_test_JNIWrapper.h

经过转换之后,方法名、变量类型什么的都变了,不过都挺有规律的:Java_包名+类名(点都换成下划线)_方法名

 

二、创建一个dll工程

首先,在VS2005中,点击新建,出现下图

 

输入Name之后,点击[OK],出现下图:

选择dll,点击finish完成即可创建dll工程

 

三、编写C/C++代码,生成dll

将步骤一种生成的头文件拷贝到工程中“Header Files”目录下,然后新建一个cpp文件,或者直接在默认生成的jnitest.cpp中编码

// jnitest.cpp : Defines the entry point for the DLL application.//#include "stdafx.h"#include "jni_test_JNIWrapper.h"#include 
//一定要加上这个#ifdef _MANAGED#pragma managed(push, off)#endifBOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ return TRUE;}#ifdef _MANAGED#pragma managed(pop)#endifJNIEXPORT void JNICALL Java_jni_test_JNIWrapper_display (JNIEnv *env, jobject obj){ printf("Hello World,JNI!\n"); return;}/** Class: jni_test_JNIWrapper* Method: sum* Signature: (DD)D*/JNIEXPORT jdouble JNICALL Java_jni_test_JNIWrapper_sum (JNIEnv *env, jobject obj, jdouble a, jdouble b){ return a + b;}JNIEXPORT jdouble JNICALL Java_jni_test_JNIWrapper_divide(JNIEnv *env, jobject obj, jdouble a, jdouble b){ return a/b;}

然后我们就可以开始编译了。

如果提示找不到“jni.h”,只需要做如下操作即可解决:

在%JAVA_HOME%\include\下找到 jni.h,在%JAVA_HOME%\include\win32\下找到jni_md.h和jawt_md.h把他们复制到“Visual Studio目录\VC\include\”下

四、继续完成Java代码调用dll

将步骤三得到的jnitest.dll放到java工程的根目录,注意是java项目的根目录,不是src目录

写个test方法测试下

package jni.test;public class JNITest {    static {        System.loadLibrary("jnitest");    }            public static void main(String[] args) {        JNIWrapper wrapper = new JNIWrapper();        wrapper.display();        System.out.println(wrapper.sum(1.0, 9.9999));        System.out.println(wrapper.divide(8.4, 2.4));    }}

不过,多数情况下,我们会把System.loadLibrary("jnitest")放在JNIWrapper中,即,

package jni.test;public class JNIWrapper {    static {        System.loadLibrary("jnitest");    }    public native void display();    public native double sum(double x, double y);    public native double divide(double x, double y);}
JNIWrapper

运行一下,输入结果为

10.99993.5000000000000004Hello World,JNI!

不知道打印“Hello World,JNI!”怎么最后执行~奇怪~

 

到这里,整个JNI调用过程就over了~~

不过还有类型转换什么的,以后再整理了....

 

推荐资料:

 

 

 

 

转载于:https://www.cnblogs.com/yejg1212/archive/2013/06/07/3125372.html

你可能感兴趣的文章
Java中使用CompletableFuture处理异步超时
查看>>
《21世纪机器人》——DeutchConn第5晶圆厂,装载码头:重启前5小时
查看>>
《中国人工智能学会通讯》——4.28 数据挖掘技术在电子数据取证中的应用
查看>>
【模式识别国家重点实验室】深度学习教你 “以貌取人”
查看>>
搞定全渠道用户体验不是梦,看这家零售巨头怎样做
查看>>
小程序分销商城开发功能
查看>>
数据中心的区块链硬件可能不会解决任何问题
查看>>
中国电信发布低时延光网络白皮书
查看>>
富瑞特装的物联网“情结”
查看>>
从“拖拽”编程开始到一个合格的程序员
查看>>
再破魔力象限 山石网科入选Gartner IDPS MQ
查看>>
从传统归档到云存储归档的演变
查看>>
灯下黑:业务安全成政企行业重大隐患
查看>>
企业级移动市场一股不能忽视的新兴势力“钉钉+”
查看>>
从零学React Native之01创建第一个程序
查看>>
一个前端与后端分离的架构实例
查看>>
数据分析师的职位划分
查看>>
如何洞察大数据的关联性
查看>>
咕咚为何值1.5亿美元?
查看>>
18个你可能不相信是用CSS制作出来的东西
查看>>