阳光小强参加了CSDN博客之星评选,如果你觉得阳光小强的博客对你有所帮助,为小强投上一票吧:http://vote.blog.csdn.net/blogstar2014/details?username=lxq_xsyu#content

在上一篇中我们了解了Android中有关JNI的使用,其实JNI是很早就有的,不是在Android创造的新技术,是SUN为我们提供的一种Java和本地代码之间相互调用的方法,这一篇我们来建立一个普通的Java工程来具体看一下Java中如何调用C/C++代码。

一、新建一个普通Java工程

package com.csdn.test;

/**
* 阳光小强 http://blog.csdn.net/dawanganban
* @author lixiaoqiang
*
*/
public class TestJNI { public native void saveHello(); public static void main(String[] args) {
TestJNI jni = new TestJNI();
jni.saveHello();
}
}

在TestJNI中我们声明了一个native方法。

二、生成C/C++头文件

SUN的JDK中已经为我们提供了一个生成对应C/C++头文件的工具(javah)

lixiaoqiangdeMac-mini:bin lixiaoqiang$ whereis javah
/usr/bin/javah
lixiaoqiangdeMac-mini:bin lixiaoqiang$

说明:我这里用的是max os系统,如果你是windows系统,在jdk目录下寻找。

找到我们工程文件所在的目录,执行javah命令如下:

lixiaoqiangdeMac-mini:bin lixiaoqiang$ pwd
/Users/lixiaoqiang/Documents/AndroidWorkspace/TestJNI/bin
lixiaoqiangdeMac-mini:bin lixiaoqiang$ javah com.csdn.test.TestJNI
lixiaoqiangdeMac-mini:bin lixiaoqiang$ ls
com com_csdn_test_TestJNI.h
lixiaoqiangdeMac-mini:bin lixiaoqiang$

可以看到为我们生成了一个com_csdn_test_TestJNI.h的头文件

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

三、生成动态库文件

下面我们打开C/C++编辑器(我这里使用的时Xcode,在Windows平台上的朋友可以使用VisualStudio)

main.cpp中我们输出一行文字,如下:

#include "com_csdn_test_TestJNI.h"
#include <iostream>
using namespace std; JNIEXPORT void JNICALL Java_com_csdn_test_TestJNI_saveHello(JNIEnv * evn, jobject obj){
cout << "hello world" << endl;
}

在编译的过程中会发现找不到jni.h和jni_md.h文件,这两个文件可以在JDK的include目录下找到,拷贝到工程中,下面将上面的工程导出动态链接库。

在导出链接库(编译)的时候在MacOS下和在Linux, Windows有所不同, 不是编译成.so或者dll, 而是MacOS自己的jnilib. 并且jni.h的目录也比较特殊, 是/System/Library/Frameworks/JavaVM.framework/Headers/, 这个需要稍微注意一下, 具体的命令如下:

lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ g++ -dynamiclib -o libhelloworld.jnilib main.cpp -framework JavaVM -I/System/Library/Frameworks/JavaVM.framework/Headers
lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$ ls
com_csdn_test_TestJNI.h jni_md.h main.cpp
jni.h libhelloworld.jnilib
lixiaoqiangdeMac-mini:TestJNI lixiaoqiang$

可以看到在该目录生成了一个libhelloworld.jnilib文件,我们将该文件拷贝到我们Java工程的bin目录下(windows下是classes目录)

向Java工程中添加加装动态库的代码(下面的static语句块中的System.loadLibrary方法)

package com.csdn.test;

/**
* 阳光小强 http://blog.csdn.net/dawanganban
* @author lixiaoqiang
*
*/
public class TestJNI { public native void saveHello(); public static void main(String[] args) {
TestJNI jni = new TestJNI();
jni.saveHello();
} static{
System.loadLibrary("helloworld");
}
}

最后将该库文件添加到Java程序可以访问的环境变量中就可以运行输出“helloworld"了。

下一篇文章我们将来看一下如何在C/C++中调用Java中的方法

深入理解Android(2)——理解Android中的JNI(中)的更多相关文章

  1. Base64编解码Android和ios的例子,补充JNI中的例子

    1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: // Base64 编码: byte [] encode =  ...

  2. Android NDK开发篇:如何使用JNI中的global reference和local reference

    JNI提供了一些实例和数组类型(jobject.jclass.jstring.jarray等)作为不透明的引用供本地代码使用.本地代码永远不会直接操作引用指向的VM内部的数据内容.要进行这些操作,必须 ...

  3. Android 深入理解Android中的自定义属性

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45022631: 本文出自:[张鸿洋的博客] 1.引言 对于自定义属性,大家肯定 ...

  4. 深入理解Android(5)——从MediaScanner分析Android中的JNI

    前面几篇介绍了Android中的JNI和基本用法,这一篇我们通过分析Android源代码中的JNI实例,来对JNI部分做一个总结. 一.通向两个不同世界的桥梁 在前面我们说过,JNI就像一个桥梁,将J ...

  5. Android多线程研究(8)——Java中的原子性理解

    一.什么是原子性 原子性是世界上最小单位,具有不可分割性.比如a=0;(a非long和double类型)这个操作是不可分割的,那么我们说这个操作是原子操作.再比如:a++;这个操作实际上是a=a+1; ...

  6. [译]:Xamarin.Android开发入门——Hello,Android深入理解

    返回索引目录 原文链接:Hello, Android_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android深入理解 本部分介绍利用Xamarin开发And ...

  7. Android Gradle 理解

    /********************************************************************************* * Android Gradle ...

  8. Android深入理解Context(二)Activity和Service的Context创建过程

    前言 上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程.需要注意的是,本篇的知识 ...

  9. Android深入理解JNI(二)类型转换、方法签名和JNIEnv

    相关文章 Android深入理解JNI系列 前言 上一篇文章介绍了JNI的基本原理和注册,这一篇接着带领大家来学习JNI的数据类型转换.方法签名和JNIEnv. 1.数据类型的转换 首先给出上一篇文章 ...

随机推荐

  1. c# 之抽象属性

    抽象属性 属性可以使类.结构.接口的成员,自然也可以是抽象类的抽象属性了,抽象属性同抽象方法一样在派生类中被实现. using System; using System.Collections.Gen ...

  2. php八大设计模式之装饰器模式

    我们都知道,得到一匹布需要大概这么几步: 1.染色 2.印花 3.裁剪 这种形式在面向对象中怎么实现呢? 面向过程[继承模式]实现: 继承模式得到需要的布料,一步一步的加工. 继承的层次越来越深,扩展 ...

  3. hdu 5412 CRB and Queries(整体二分)

    题意 动态区间第k大 (n<=100000,m<=100000) 题解 整体二分的应用. 与静态相比差别不是很大.(和CDQ还有点像)所以直接上代码. #include<iostre ...

  4. [USACO07MAR]每月的费用Monthly Expense

    题目:POJ3273.洛谷P2884. 题目大意:有n个数,要分成m份,每份的和要尽可能小,求这个情况下和最大的一份的和. 解题思路:二分答案,对每个答案进行贪心判断,如果最后得出份数>m,则说 ...

  5. 软raid 实验

    RAID0 条带卷 2+ 100% 读写速度快,不容错 RAID1 镜像卷 2 50% 读写速度一般,容错 RAID5 带奇偶校验的条带卷 3+ (n-1)/n 读写速度快,容错,允许坏一块盘 RAI ...

  6. vue深究第一弹:computed与watch的异同

    最近在开发vue的过程中,不断用到了计算属性(computed)和观察者(watch),从逻辑上感觉它们很相似,但是尝试混用它们的时候,又出现了一些问题,那么它们到底有什么异同呢? 1. comput ...

  7. [NOIP2009] 靶形数独(搜索)

    P1074 靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士 ...

  8. 绿色版SecureCRT启动崩溃,遇到一个致命的错误且必须关闭

    百度搜了半天,大家都是说删除注册表的VanDyke就能解决问题,但是我用的是绿色版的,删除VanDyke后还不行. 然后试了一下重新解压出一个绿色版的SecureCRT,发现能用. 但之前我配置了很多 ...

  9. django-xadmin使用之更改菜单url

    环境:xadmin-for-python3 python3.5.2 django1.9.12 1. 在模块的adminx.py文件中增加以下代码: class AdminSettings(object ...

  10. poj 2533 Longest Ordered Subsequence 最长递增子序列(LIS)

    两种算法 1.  O(n^2) #include<iostream> #include<cstdio> #include<cstring> using namesp ...