java jni编译
来源:互联网 发布:淘宝上好的女鞋外贸店 编辑:程序博客网 时间:2024/04/29 10:17
零 绪论
今天看安卓的源码。发现很多东西都是jni的东西。所以我也要看看java是怎么和jni通信的。那么就涉及到了编译问题。这种情况下涉及到交叉编译,很烦。网络上也是哀嚎声一片。但是我没有遇到那么多的困难。
首先注意几个要点
1你要知道你运行java的程序的版本。我是64位的
2你要知道你gcc编译器编译出来的东西是多少位的
我想很多情况下都是可能gcc编译出来的是32位的东西,你拿到64位jre上运行。可能是这样导致的错误。
说一下我系统的配置情况。
我是采取全线64位策略
win7 64位
jdk 64位
jre64位
mingw64位
下面我一步一步讲解如何编译
一准备
工具准备 win7 jdk64 jre64都是很好弄到的。重点是mingw64.这个东西确保你使用gcc的时候编译出来的是64位的动态链接库,好给64位的jre使用。
其中mingw64很难再官网上下载,所以我是在一个
这里下载出来的
下载出来是个压缩包把压缩包里面的
解压出来。我放到了D:\Program Files里面
至此你的mingw64已经安装完成。为了能在cmd里面找到你的gcc。你需要把
D:\Program Files\mingw64\bin
这个路径添加到你的path环境变量里面。如何添加环境变量另行百度。
这样你的gcc方面已经配置好。
二 编译
1准备测试代码
下面给出测试代码。这个代码随处可见
//HelloNative.javaclass HelloNative{ public static native void greeting();}
用javac编译这个产生HelloNative.class命令如下
javac HelloNative.java
如果找不到javac命令在哪里。那么说明你的jdk没有放到path变量里面。解决方法和把gcc放到path里面一样
你需要运行javah命令,根据HelloNative.class生成一个用于编写c的头文件
javah HelloNative
这时候会产生一个这样的文件HelloNative.h
内容是
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloNative */#ifndef _Included_HelloNative#define _Included_HelloNative#ifdef __cplusplusextern "C" {#endif/* * Class: HelloNative * Method: greeting * Signature: ()V */JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
这个是自动生成的头文件。现在你需要自己编写一个c文件,实现这个native代码
//名字是HelloNative.c#include<stdio.h>#include"HelloNative.h"JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv* env,jclass cl){ printf("hello native");}
到这里之后。你的c文件也准备好编译了。
2编译出dll
如果简单的运行下面的命令是无法编译出来的
gcc HelloNative.c
错误有几个方面
1我们要生成一个连接库,并不是一个exe文件。
所以要加上参数-shared -o helloNative.dll HelloNative.c
这里的-shared是说我们要一个动态链接库 -o helloNative.dll指定我输出出来的名字
现在命令是这个样子
gcc -shared -o helloNative.dll HelloNative.c
2我们引用了jni这个头文件,但是标准的c里面没有这个头文件,我们需要指定说这个头文件去哪里找。我们要添加
-IC:\Java\jdk1.8.0_60\include
-IC:\Java\jdk1.8.0_60\include\win32
这两个参数可能你会有变化。因为我的jdk安装在C:\Java\jdk1.8.0_60\。所以自然我们就需要指定搜索路径是C:\Java\jdk1.8.0_60\include 。 -I表示头文件搜索路径
现在的编译命令是这样的
gcc -IC:\Java\jdk1.8.0_60\include -IC:\Java\jdk1.8.0_60\include\win32 -shared -o helloNative.dll HelloNative.c
当然还有很多奇怪的问题
我们要加参数
-Wl,–kill-at
其实-WI是告诉gcc后面的参数–kill-at是给链接器的
–kill-at告诉链接器功能如下。
–kill-at
If given, the stdcall suffixes (@nn) will be stripped from symbols before they are exported.
[This option is specific to the i386 PE targeted port of the linker]
下面是个网友的解释
On Microsoft systems (PE executable/DLL format), the calling convention stdcall generates mangled symbols of the form symbolname@number. From the description, –kill-at causes the names exported from DLLs to just be symbolname even if they use the stdcall calling convention.
就是说在链接库里面的函数名字表示方式要做改变。不然jvm不能识别。
-D_JNI_IMPLEMENTATION_
这个选项的意思是-D是告诉gcc后面的东西定义一个宏。
gcc -D选项在man中的说明如下:
-D name
Predefine name as a macro, with definition 1.
还有加上一个参数-Wall
这个参数说
-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
就是打开所有警告。好像可以关闭的样子
现在我终极的编译命令是
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,–kill-at -IC:\Java\jdk1.8.0_60\include -IC:\Java\jdk1.8.0_60\include\win32 -shared -o helloNative.dll HelloNative.c
总算完成了
编译之后会产生一个文件叫helloNative.dll
三测试
我们可以写一个测试文件
//test.javapublic class test{ public static void main(String args[]) { HelloNative.greeting(); } static { System.loadLibrary("helloNative"); }}
然后编译运行这个文件我们可以得到这样的结果
备注
1我们所有的代码都是放到C的根目录下面的
2目录内容如下
- Java JNI编译小记
- java jni编译
- mac编译jni 调用java
- JAVA调用JNI,GCC编译
- java jni 动态编译指令
- [JAVA]MinGW-GCC 如何编译JNI程序
- 关于java jni编译javac javah的问题
- java通过jni调用c编译的dll或so
- ubuntu PJSIP编译java库及jni生成,开放新jni接口
- VS2005 JNI编译
- JNI-ndk编译cpp
- Android JNI 编译注意事项
- JNI 编译问题
- jni编译过程
- jni开发编译
- jni编译方法
- android JNI编译注意事项
- 命令行编译JNI
- HDU 5515 Game of Flying Circus (2015沈阳G题&&二分模拟)
- python 模块学习
- Java多线程 学习笔记(一)
- Android Studio下的ndk开发
- 软件构架、架构和框架的区别
- java jni编译
- xml的使用
- 沈阳皮童:几个小窍门专治皮鞋变形
- iphone数据存储之 Core Data的使用(一)
- Android input 按键处理过程
- iOS Soap request 封装 附github地址
- Asp.net 学习宏观总结
- win10和ubuntu双系统下如何删除ubuntu
- 一致性哈希及java实现