在Java代码中通过JNI调用C函数的步骤如下:

第一步:编写Java代码

 class HelloJNI{
native void printHello();
native void printString(String str); static {System.loadLibrary("hellojni");} public static void main(String args[]) {
HelloJNI myJNI = new HelloJNI(); myJNI.printHello();
myJNI.printString("Hello World from c fun"); } }

第二步: 编译Java代码

    javac HelloJNI.java   生成HelloJNI.class文件

第三步: 生成C语言头文件

    javah HelloJNI   生成HelloJNI.h头文件    

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */ #ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printHello
(JNIEnv *, jobject); /*
* Class: HelloJNI
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printString
(JNIEnv *, jobject, jstring); #ifdef __cplusplus
}
#endif
#endif

第四步: 编写C代码

  要注意c代码必须得依照上面头文件的方式编写,和普通的c函数有区别

 #include"HelloJNI.h"
#include<stdio.h> JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj) {
printf("Hello World!\n");
return;
} JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv * env, jobject obj, jstring string) {
const char *str = (*env)->GetStringUTFChars(env,string,);
printf("%s!\n",str);
return;
}

第五步: 生成C共享库

  CodeBlocks下:

   File - New - Project - Shared library - Go

因为HelloJNI.h中有这样的一句#include <jni.h>,标准的库文件下是没有这个文件的,但这个文件可以在JDK的安装目录下面找到

为了能够顺利编译,需要把相应文件复制到C编译器的头文件存放处,像下面这样:

编译生成C共享库文件:

不过CodeBlocks默认生成的文件前面加了前缀lib,需要手动去掉,但运行是还是出了问题:

 D:\hixin\C>java HelloJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\hixin\C\hellojni.d
ll: Can't load IA 32-bit .dll on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at HelloJNI.<clinit>(HelloJNI.java:)

大意是生成的dll不是64位的,看了网上最新版的vs似乎是可以生成64位dll,算啦不纠结这个啦

《Android进阶》之第一篇 在Java中调用C库函数的更多相关文章

  1. Android开源项目第一篇——个性化控件(View)篇

    本文为那些不错的Android开源项目第一篇——个性化控件(View)篇,主要介绍Android上那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Ga ...

  2. Android解析ClassLoader(一)Java中的ClassLoader

    Android解析ClassLoader(一)Java中的ClassLoader

  3. java中调用dll文件的两种方法

    一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676   JNativ ...

  4. java中调用js脚本

    JDK1.6加入了对Script(JSR223)的支持.这是一个脚本框架,提供了让脚本语言来访问Java内部的方法.你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚本.这个脚本API允许你为脚 ...

  5. 如何在Java中调用Python代码

    有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...

  6. 在Java中调用Python

    写在前面 在微服务架构大行其道的今天,对于将程序进行嵌套调用的做法其实并不可取,甚至显得有些愚蠢.当然,之所以要面对这个问题,或许是因为一些历史原因,或者仅仅是为了简单.恰好我在项目中就遇到了这个问题 ...

  7. 在Java中调用Python代码

    极少数时候,我们会碰到类似这样的问题:与A同学合作写代码, A同学只会写Python,不熟悉Java ,而你只会写Java不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方 ...

  8. Java中调用MatLab返回值

    当在Java中使用MatLab函数时,由于语言语法的不同,Matlab返回多个数据时,想在Java中获取到并进行使用.查阅了网上资料,翻箱倒柜加上自己实战,得出方法如下: 如MatLab函数返回的是N ...

  9. Java中调用c/c++语言出现Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.testPrint(Ljava/lang/String;)V...错误

    错误: Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.testPrint(Ljava/lang/S ...

随机推荐

  1. 《Java Performance》笔记1——性能分析基础 2

    4.内存使用率: 内存使用率的相关属性包括页面调度或页面交换.加锁.线程迁移中的让步式和抢占式上下文切换. 当应用运行所需的内存超过可用物理内存时,就会发生内存页面交换,系统在进行页面交换或使用虚拟内 ...

  2. 4.Maven仓库

    1. 何为Maven仓库 Maven仓库就是统一存放所有依赖的地方,其他所有项目都可以在仓库里通过坐标找到所需要的依赖. 2. 仓库的布局 任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中 ...

  3. 简聊iOS支付集成(支付宝和微信支付)

    一.支付集成是什么 1.现在大部分app都有快捷支付功能,支付集成将第三方支付平台集成到自己的项目中,能够完成自己项目中的支付功能, 二.支付集成的使用 <1>.支付宝: 下载SDK和De ...

  4. 浅谈如何让 Bootstrap 3兼容IE8浏览器

    Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目.-- Bootstrap 官网 Bootstrap 来自 Twitter,是目前最 ...

  5. 打造比Dictionary还要快2倍以上的字查找类

    针对一个长度为n的数组. [1,2,3,4,5,6,7,8,9] 最快的通用查找类是Dictionary其采用hashcode算法,复杂度为O(1). 而上大学时,最快的查找法为二分查找法,复杂度为O ...

  6. 设计模式总结(Java)—— 适配器模式

    适配器模式中引入了一个被称为适配器(Adapter)的包装类,而它所包装的对象称为适配者(Adaptee),即被适配的类.适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用.也就是说:当客户 ...

  7. Nginx Access Log日志统计分析常用命令

    Nginx Access Log日志统计分析常用命令 IP相关统计 统计IP访问量 awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时 ...

  8. 如何用unity3d实现发送带附件的邮件

    以Gmail为例.点击屏幕的Capture按钮得到当前屏幕截图,点击Send按钮将之前的截图作为附件发送邮件. using UnityEngine; using System.Collections; ...

  9. 【 js 模块加载 】深入学习模块化加载(node.js 模块源码)

    一.模块规范 说到模块化加载,就不得先说一说模块规范.模块规范是用来约束每个模块,让其必须按照一定的格式编写.AMD,CMD,CommonJS 是目前最常用的三种模块化书写规范.  1.AMD(Asy ...

  10. Spring + Mybatis 项目实现动态切换数据源

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. ...