首页 > 代码库 > Java通过JNI调用C
Java通过JNI调用C
Java调用C有多种方式,本文介绍笔者最近的学习过程,避免今后再犯类似的错误。
首先,Java肯定是调用C的动态链接库,即通过编译器编译后的dll/so文件。
下面介绍gcc编译dll的方法。
一般情况把主函数,子函数定义,子函数声明(全局变量,宏等)分别放在不同的文件中。
我们主要对子函数编译生成可用的dll,供主函数调用。
有一个工程,里面有三个文件,分别是
#include <stdio.h>#include "test.h"int main(int argc, char *argv[]) { printf("2 + 3 = %d\n", sum(2, 3)); return 0;}
1 #include <stdio.h>2 #include"test.h"3 4 int sum(int a, int b)5 {6 return a + b;7 }
#ifndef _TEST_H_DEVC_#define _TEST_H_DEVC_int sum(int a, int b);#endif
假如想在main.c中调用test.c函数的dll文件,可以编译test.c的动态链接库
在Windows平台上安装MinGW, 即可模拟Linux下的gcc的编译器。
得到test.dll文件。接着把,main.c 、test.h、test.dll 放到另一个文件夹中,编译得到
可执行文件,rs.exe。运行结果得到
下面介绍javah编译C的头文件,本文主要介绍在MyEclipse下的运行步骤。
先配置javah命令如下:
其中,需要自主配置一下三个参数
Location:是你本机的javah.exe所在的路径。Working Directory: ${project_loc}/binArguments: -classpath .;./classes -d "${project_loc}" -jni ${java_type_name}
配置好后,就可以一键操作生成java所需要的头文件了。
例子如下:
工程名字:zz-testdll
1 package main; 2 3 import testdll.Sum; 4 5 public class Main { 6 static{ 7 System.loadLibrary("test"); 8 } 9 public static void main(String[] args){10 int rs = Sum.mSum();11 System.out.println(rs);12 }13 }
1 package testdll;2 3 public class Sum {4 public native static int mSum();5 }
选中Sum.Java文件,然后运行配置好的javah命令,即可得到上图中的testdll_Sum.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class testdll_Sum */#ifndef _Included_testdll_Sum#define _Included_testdll_Sum#ifdef __cplusplusextern "C" {#endif/* * Class: testdll_Sum * Method: mSum * Signature: ()I */JNIEXPORT jint JNICALL Java_testdll_Sum_mSum (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
下面要实现testdll_Sum.h文件中的方法
(因为gcc编译器和VC++编译器的实现方式的不同,参看http://www.blogjava.net/lixf/archive/2006/01/09/25177.html)
我们需要修改生成的testdll_Sum.h中方法的名字,在函数的名字前面加一个下划线即可。
更改后的testdll_Sum.h如下:
1 /* DO NOT EDIT THIS FILE - it is machine generated */ 2 #include <jni.h> 3 /* Header for class testdll_Sum */ 4 5 #ifndef _Included_testdll_Sum 6 #define _Included_testdll_Sum 7 #ifdef __cplusplus 8 extern "C" { 9 #endif10 /*11 * Class: testdll_Sum12 * Method: mSum13 * Signature: ()I14 */15 JNIEXPORT jint JNICALL _Java_testdll_Sum_mSum16 (JNIEnv *, jclass);17 18 #ifdef __cplusplus19 }20 #endif21 #endif
实现的方法如下:
#include "testdll_Sum.h"//前两个参数(env和obj)可以忽略JNIEXPORT jint JNICALL _Java_testdll_Sum_mSum (JNIEnv * env, jclass obj) { printf("Hello world!\n"); return 5; }
在Java的include文件夹下得到三个文件,一共5个文件供编译使用。
得到test.dll,放在Java工程的运行目录下即可。
选中Main.Java文件,run,得到。
在我写完后,得知Java通过JNA可以很方便的调用C文件,有机会学习下。
以上内容,仅供参考。
Java通过JNI调用C