JNI的全称是java native interface,用来调用某些特定于系统平台或者硬件的操作,但是它只能调用c/c++的代码,若是其它语言代码,只能通过c/c++进行二次调用。
关于JNI的完整技术文档,大家可以查看下面这个网址:
下面我们看下JNI如何执行回调函数:
我们知道在c/c++回调函数可以通过函数指针执行,但是在Java中已经没有指针的概念,在这里,我们先传递一个类对象给native函数,然后再dll中调用期望的函数即可。
下面的这个例子中,我们通过回调传递一个字符串给java,这在java和c/c++混合编程时传递dll内部的出错或其他信息到java层是很有用的。
1.
首先创建一个java类文件,封装一个native函数和一个用于回调的函数
package
jni;
public
class
Log
…
{
static … {
System.loadLibrary( “ mylib “ ); } // 用来回调,输出c代码层的信息 public void output(String out) … {
System.out.println(out); } // native函数,用来传递对象 public native void test(Log log); public static void main(String[] args) … {
Log log = new Log(); log.test(log); } }
2.
调用javah命令,生成对应的c/c++都文件
/**/
/* DO NOT EDIT THIS FILE – it is machine generated */
#include
<
jni.h
>
/**/
/* Header for class jni_Log */
#ifndef _Included_jni_Log #define _Included_jni_Log #ifdef __cplusplus extern
“
C
“
…
{
#endif /**/ /* * Class: jni_Log * Method: test * Signature: (Ljni/Log;)V */ JNIEXPORT void JNICALL Java_jni_Log_test (JNIEnv * , jobject, jobject); #ifdef __cplusplus }
#endif #endif
3.
利用vc和生成的头文件完成一个dll
#include
<
windows.h
>
#include
“
jni_Log.h
“
int
WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReasion,PVOID pvReserved)
…
{
return TRUE; }
JNIEXPORT
void
JNICALL Java_jni_Log_test(JNIEnv
*
env, jobject obj, jobject log)
…
{
jclass cls = ( * env) -> GetObjectClass(env, log); jmethodID jmid = ( * env) -> GetMethodID(env, cls, “ output “ , “ (Ljava/lang/String;)V “ ); jstring info = ( * env) -> NewStringUTF(env, “ i am a error! “ ); ( * env) -> CallVoidMethod(env,log, jmid,info); ( * env) -> ReleaseStringUTFChars(env,info,( * env) -> GetStringUTFChars(env, info, FALSE)); }
编译完成后,将mylib.dll放到与jni同级的目录中,运行命令java jni.Log,即可看到控制台成功打印信息
“ i am a error! “。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100529.html 原文链接:https://javaforall.net