花了三天时间,终于把这个环境和实现都弄通了一遍。

先来个总纲:

准备工作:jdk环境,eclipse,gcc环境,cdt插件

a.编写带有native声明的java类,

b.编译java类

c.用javah -jni生成头文件

d.使用其他语言(c、c++)实现native method

e.生成动态链接库

考虑到自己很久没有接触vs和vc,此次实现jni使用eclipse的CDT插件,所以第一步是安装CDT插件,CDT插件的运行还依赖于系统的c、c++编译器,win7下一个不错的c编译器为MinGW,所以先下载安装配置MinGW,http://www.mingw.org/

安装:全部选中

添加环境变量:path里添加C:\MinGW\bin

ok,试一下有没有成功,win+r,cmd,gcc -v,如果出现如下图就表示可正常使用gcc编译器。

下一步可以安装CDT了,打开eclipse,help,install new software,折腾吧,这里有点忘了,安装的时候可能会有冲突,安装完了就可以用file>new>c projet了。

准备工作到这里就结束了,开始总纲中的步骤

a.新建一个java项目,新建一个java类

package lan;

public class Test {
public native void hello();
static {
System.out.println("Test...static...");
System.loadLibrary("hello");
}
public static void main(String[] args) {
new Test().hello();
} }

b.编译java类
进入cmd命令行下lan目录

javac lan/Test.java

生成Test.class
c.用javah -jni生成头文件

javah -jni -cp . lan.Test

解释一下这个命令:javah -jni 生成头文件,-cp . ,-cp是指明类搜索,.是指本目录,后面加上类名,要包名加类名写全。头文件出现在执行命令的路径下。lan_Test.h
d.使用其他语言(c、c++)实现native method,File>new>c project,选择Shared Library Empty Project>MinGW GCC

把刚刚javah生成的lan_Test.h头文件拷贝到这个项目中,

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class lan_Test */ #ifndef _Included_lan_Test
#define _Included_lan_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: lan_Test
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_lan_Test_hello
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif

可见这里有一个函数的声明,然后新建一个source文件,Test.c写入内容如下

/*
* Test.c
*
* Created on: 2015-2-27
* Author: azul
*/
#include <stdio.h>
#include "lan_Test.h" JNIEXPORT void JNICALL Java_lan_Test_hello
(JNIEnv *, jobject){
printf("hello,world!hello,C!");
return;
}

e.生成dll文件

E:\new_workspace\CallTest>gcc -I "C:\Java\jdk1.7.0_51\include" -I "C:\Java\jdk1.7.0_51\include\win32"  -shared Test.c -o hello.dll
Test.c: In function 'Java_lan_Test_hello':
Test.c:11:3: error: parameter name omitted
(JNIEnv *, jobject){
^
Test.c:11:3: error: parameter name omitted

结果有这个错误,是由于c和c++的区别造成的,将c源文件改为c++的,即将Test.c更名为Test.cpp,-I是为了将缺少的两样,jni.h和jni_md.hjava_home中的include和其下的win32包含进来。

ok,dll文件生成,试一下运行java程序

E:\new_workspace\Test\src\lan>java -Djava.library.path="E:\new_workspace\CallTest"  -cp ../ lan.Test
Test...static...
Exception in thread "main" java.lang.UnsatisfiedLinkError: lan.Test.hello()V
at lan.Test.hello(Native Method)
at lan.Test.main(Test.java:10) E:\new_workspace\Test\src\lan>

说明程序运行了,可是链接出错了,查文档,看论坛,参考 http://bbs.csdn.net/topics/80272618 所说,应该是由于vc和gcc生成dll库的时候命名规则导致的函数名前缀"_"差异,重新生成dll文件

E:\new_workspace\CallTest>gcc -I "C:\Java\jdk1.7.0_51\include" -I "C:\Java\jdk1.7.0_51\include\win32"  -shared Test.cpp -Wl,--kill-at -o hello.dll

再次运行java程序

E:\new_workspace\Test\src\lan>java -Djava.library.path="E:\new_workspace\CallTest"  -cp ../ lan.Test
Test...static...
hello,world!hello,C!
E:\new_workspace\Test\src\lan>

非常好,成功了。放在eclipse中用run运行一下,将dll文件放入项目中,

运行结果如图:

ok!成功,这里主要注意的几个问题是java运行程序时候寻路径的问题,提示找不到类的时候可以加上-cp,运行文件的时候用包名/类,运行类的时候用包名.类

这个故事先告一段段落了。

jni调用的更多相关文章

  1. JAVA的JNI调用

    由于JNI调用C和调用C++差不多,而且C++中可以混合写C代码,所以这里主要是写关于JNI调用C++的部分. 一般步骤: 先是写普通的Java类,其中包括本地方法调用.  然后编译这个Java类,调 ...

  2. HAL中通过JNI调用java方法【转】

    转载请注明本文出处:http://www.cnblogs.com/xl19862005 作者:Xandy 由于工作的需要,最近一直在研究HAL.JNI.Java方法之间互调的问题,并做了如下一些记录和 ...

  3. JAVA使用JNI调用C++动态链接库

    JAVA使用JNI调用C++动态链接库 使用JNI连接DLL动态链接库,并调用其中的函数 首先 C++中写好相关函数,文件名为test.cpp,使用g++编译为DLL文件,指令如下: g++ -sha ...

  4. 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)

    OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...

  5. JNI调用测试

    有需求使用JNI调用,籍着这个机会按照<Linux下测试Java的JNI(Java Native Interface)>上进行了下测试. 这篇文章记录得很清楚了,对原理未做深入的分析,希望 ...

  6. Java JNI调用c语言的dll测试

    最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...

  7. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

  8. Ubuntu下,在Eclipse中使用JNI调用ffmpeg

    Android的应用层开发大部分还是采用JAVA,如果想使用ffmpeg库,就必须利用JNI,使得Java可以调用C/C++的库. JNI其实就是定义的一个转接接口,可以让Java的代码调用C/C++ ...

  9. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

  10. 移动mmbilling似乎有个BUG,通过JNI调用会抛出异常

    有人用JNI调用过mm么?不知道你成功了没有,我试了多种方法,有一个错误始终存在,怀疑上个BUG.使用方式: 通过NativeActivity的clazz获取ClassLoader,然后找到mm.pu ...

随机推荐

  1. python命令行开发--click

    目录 前言 安装 快速上手 参考文档 前言 按照官方的介绍:Click 是一个利用很少的代码以可组合的方式创造优雅命令行工具接口的 Python 库. 它是高度可配置的,但却有合理默认值的" ...

  2. 监控系统grafana常见问题合集

    监控系统搭建完毕后,使用中确实存在不少的习惯问题. 系统组成: 展示界面:Grafana 核心系统:Promethus snmp监控:SNMP Exporter ping监控:Blackbox Exp ...

  3. Beautiful Soup库的安装

    安装:'以管理员身份运行'cmd 执行pip install beautifulsoup4 Beautiful Soup库的理解: 解析.遍历.维护标签树的功能库 那么何为标签树? 1 from bs ...

  4. Unix时间戳转化成普通日期

    var time = 1630634462000; //13位数 var unixTimestamp = new Date(time); var commonTime = unixTimestamp. ...

  5. php中的错误异常处理

    作者:小涵 |  阅读: 1636 在PHP5中添加了类似于其它语言的错误异常处理模块.在PHP代码中所产生的异常可被throw语句抛出并被catch语句捕获.需要进行异常处理的代码都必须放入 在PH ...

  6. cmake:macro,function中ARGV,ARGN参数的区别

    cmake中的宏(macro)和函数(function)都支持动态参数 变量ARGC记录传入的参数个数 变量ARGV0,ARGV1,...顺序代表传入的参数 变量ARGV则是一个包含所有传入参数的li ...

  7. Luckysheet文档 设置表格内容和背景色

    Luckysheet的使用参考  https://mengshukeji.gitee.io/LuckysheetDocs/zh/guide/api.html#%E5%8D%95%E5%85%83%E6 ...

  8. Java编写1到100质数之和

    int sum = 0; int k = 2; // 找出1-100的质数之和 for (int i = 2; i <= 100; i++) { // i值为2,质数为除去1和自身整除的数 j初 ...

  9. [服务器]Windows Server 2008 64位1核1G安装SQL Server2008

    本文为原创文章,转载请注明出处!我的博客地址:http://www.cnblogs.com/txwd 这台服务器是2017年初买的,那时候1核1G,3年要1500.不过现在便宜了,2核4G,3年也就1 ...

  10. Amd,Cmd, Commonjs, ES6 import/export的异同点

    Amd,Cmd, Commonjs, ES6 import/export等均是模块化方案 1.Commonjs使用在Nodejs上,加载模块是同步的. 2.Amd是requirejs在推广过程中对模块 ...