码迷,mamicode.com
首页 > 编程语言 > 详细

[Java JNI] [Windows] [Visual Studio] [DLL] [UnsatisfiedLinkError]

时间:2018-04-10 15:10:53      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:jnienv   导致   动态   include   产生   env   int   stdio.h   char   

  研究发现, 无论是使用gcc还是g++, GCC for Windows生成DLL动态链接库时都会修改我们的符号, 导致即使加载了动态链接库, JVM仍然找不到符号, 从而产生java.lang.UnsatisfiedLinkError错误

  所以还是使用微软自家的VS来生成DLL比较妥当, 由于VS命令行错综复杂, 建议使用图形界面, 下面是配置要点.

  (1) 包含jdk目录下的include和include\win32目录, 便于查找jni.h和jni_md.h

技术分享图片

  (2) 如使用纯C代码, 则包含jni.h前插入代码 #undef __cplusplus 可使代码提示更友好.

  配置好后, 我们来实现一个Java native方法.

package pkg;

public class WinMessageBox {
	
	/**
	 * 弹出一个全局对话框
	 * @param label 窗口标题
	 * @param content 窗体内容
	 * @return 调用结果 */
	public static native boolean showMessageBox(String label, String content);

}

  使用javah.exe来生成一个声明了WinMessageBox类中需要实现的native方法的头文件

javah pkg.WinMessageBox

  得到文件pkg_WinMessageBox.h, 使用VS实现它.

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

#ifndef _Included_pkg_WinMessageBox
#define _Included_pkg_WinMessageBox
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     pkg_WinMessageBox
 * Method:    showMessageBox
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT jboolean JNICALL Java_pkg_WinMessageBox_showMessageBox
  (JNIEnv *, jclass, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif

  

#undef __cplusplus
#include "H:\Code\EclipseWorkSpace\TEST\bin\pkg_WinMessageBox.h"

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

JNIEXPORT jboolean JNICALL Java_pkg_WinMessageBox_showMessageBox(JNIEnv *env, jclass clazz, jstring label, jstring content){
	MessageBoxW((HWND) NULL, (LPCWSTR) (**env).GetStringChars(env, content, 0), (LPCWSTR) (**env).GetStringChars(env, label, 0), MB_OK);
	srand((UINT) time(0));
	return rand() % 2 > 0 ? TRUE : FALSE;
}

  生成项目后, 编写测试

技术分享图片

 

在这个过程中我们发现, 虽然我们需要使用动态链接库JVM.dll中的函数, 但是我们并不需要显式地去链接它, 这是因为我们的对JVM函数的调用都是使用形参中传入的JNIEnv指针指向的结构体对象指针指向的结构体对象中的一张函数指针表调用的, Java运行时会为我们打包JVM上下文, 并将这张表填好, 在调用本地方法时将其作为参数传入, 这样一来我们就可以在本地方法中使用表中的指针调用函数了.

[Java JNI] [Windows] [Visual Studio] [DLL] [UnsatisfiedLinkError]

标签:jnienv   导致   动态   include   产生   env   int   stdio.h   char   

原文地址:https://www.cnblogs.com/develon/p/8778478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!