当前位置: 首页>编程语言>正文

c java语言 语言 java运行c语言

JNI实现java调用C语言实现底层代码

          在class="superseo">java中,很多sun公司定义的java代码中, 都有native方法, 它没有方法体,只有参数和返回值。这个方法究竟是什么呢?它其还是一个java和C/C++的一个接口方法。通过native方法, java可是实现调用C/C++的函数。

           多数人是通过JNI和NIO的方法实现。当前我学习的是JNI

           JNI: java native interface (java本地接口调用)。java代码中,使用native方法,我们就以所有学习程序设计语言第一个程序HelloWorld来做介绍。

           具体实现:

                  1)java部分代码:

public class HelloWorld{
	static{
		System.loadLibrary("src/test1");
	}
	public native void display();
	public static void main(String[] args){
		new HelloWorld().display();
	}
}

             jvm机制简单介绍一下,jvm采用懒加载机制,在调用一个类的时候,采取加载。在HelloWorld类中, static静态块加载进内存中, 

System.loadLibrary("src/test1");会自动调用src/test1这个文件,该文件就是C/C++生成的.dll依赖文件。这里是test1.dll。当加载的时候,就会调用.dll文件,调用C代码。

              那么我们先将Helloworld.java 通过javac编译,然后使用javah命令,会生成HelloWorld.h头文件,用于C/C++中加入到代码中。使用 :javah HelloWorld  

HelloWorld.h头文件,会看到是一些宏定义什么的。

/* DO NOT EDIT THIS FILE - it is machine generated */
 #include <jni.h>
 /* Header for class HelloWorld */


 #ifndef _Included_HelloWorld
 #define _Included_HelloWorld
 #ifdef __cplusplus
 extern "C" {
 #endif
 /*
  * Class:     HelloWorld
  * Method:    display
  * Signature: ()V
  */
 JNIEXPORT void JNICALL Java_HelloWorld_display
   (JNIEnv *, jobject);


 #ifdef __cplusplus
 }
 #endif
 #endif

        这里的 NIEXPORT void JNICALL Java_HelloWorld_display (JNIEnv *, jobject);就是生成的C类型的java方法。

2)编写C/C++,,使用visual stuio 2010

新建cpp文件,文件名和java中 System.loadLibrary("src/test1");这个test1文件名相同, 因为到时候生成的dll文件时以CPP文件名命名。

新建步骤:win32项目--->dll(这里输出符号打钩)

JNIEXPORT void JNICALL Java_HelloWorld_display(JNIEnv *, jobject);

函数是写了,但是函数从哪儿来??当然是HelloWorld.h中声明咯,就在cpp文件中引入该头文件。而 JNIEnv *,等这些类型,都是哪里定义的呢?看Helloworld.h头文件,,它引入了个jni.h头文件,这个头文件其实在JDK安装目录下%JAVA_HOME%\include 而jni.h又引用了jni_md.h  这个在 %JAVA_HOME%\include\win32目录下,然后把这2个头文件拷贝到C工程下。

运行,生成dll,将它拷贝到java目录中, 但是运行的时候发现报异常, java.lang.UnsatisfiedLinkError: Couldn ‘t load testcpp: findLibrary returned 。。Can't load IA 32-bit .dll on a AMD 64-bit platform,,是dll的格式为32位的,而平台式64位的, 百度,,然后知道了,将运行那里本身是win32,改成x64就OK。编译,重新拷贝一次dll,运行,就可以输出Hellowolrd这个字符串,,是不是很神奇?


https://www.xamrdz.com/lan/5cj1967325.html

相关文章: