java通过 jni 调用C++动态库----上篇

原文链接:https://blog.csdn.net/Oyasimi1412/article/details/82259597

1:首先新建一个java的项目(项目)名为的HelloWorld

 

 

 

 暂时不创建moudle,这里简单例子不需要这个。

2:在SRC目录上创建一个包(包)名为com.jni

 

 

 3:再在包com.jnishang创建两个类HelloWorld和Test Dll

大家同理创建TestDll类。

helloWorld.java源代码如下:

package com.jni;
 
public class HelloWorld {
    static
    {  
        System.loadLibrary("mydll");
    }
    
    public native void displayHelloWorld();
}

上面的mydll就是我们下一篇将要用到的动态库,这里先这样写。

TestDll.java源代码如下:

package com.jni;
 
public class TestDll {
    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        HelloWorld helloWorld = new HelloWorld(); 
        helloWorld.displayHelloWorld();
    }
}

相关代码注意在ecilpse里面做一下保存工作,不然后面的命令行有可能失败

到这里准备工作基本结束:

先编译HelloWorld.java,我们这里使用命令行编译

先在电脑到达这个目录d:\ Eclipse的工作空间\的HelloWorld \ SRC \ COM \ JNI

也就是两个的的java文件所在目录,如下:

 

 shift +鼠标右键进入命令行,如下:

。我们先编译出类文件使用命令javac的的:

命令如下:javac HelloWorld.java

 

 

成功后在同一目录就可发现HelloWorld.class的文件了,如下:

 

 

 

接下来要编译我们最重要的.H文件了,这里我搞了很久,本来是用JAVAH命令来编译,网上也有大量的相关教程,但是我用的jdk10,新版本的JDK已经去除了javah.exe ,也就是说不能再用javah命令了,jdk9开始就提供了javac -h命令代替,经过一些尝试,我还是弄出来了javac -h命令的用法。

希望了解JAVAH用法的朋友请参考别的同学的分享,由于我本机已经无法执行JAVAH命令,所以没有这方面的说明给大家,这块的文档网上应该很多

我们需要先让命令行回到D:\ eclipse-workspace \ HelloWorld \ src目录,通过两个命令行cd ..就可以回来,如下:

现在我们已经回到了D:\ eclipse-workspace \ HelloWorld \ src目录,接下来执行javac -h命令,这里的目录一定不要弄错了,希望读者,按要求操作。

执行javac -h.COM \ JNI \ HelloWorld.java

 

 

 然后就可以在SRC目录下找到com_jni_HelloWorld.h

 

 到了这里,我们与C ++交互的.h文件就有了,com_jni_HelloWorld.h源码如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jni_HelloWorld */
 
#ifndef _Included_com_jni_HelloWorld
#define _Included_com_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jni_HelloWorld
 * Method:    displayHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_jni_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

注意,不要修改这个头文件。

到这里,关键的头文件就生成了,接下来一篇介绍如何使用生成的这个头文件

java通过 jni 调用C++动态库----下篇

上篇介绍了 通过命令行生成了一个.h 文件  com_jni_HelloWorld.h

本章介绍如何使用这个文件

先创建DLL,过程如下:

工具vs2017     

创建动态库DLL给第三方使用

步骤:

1,文件 - >新建 - >项目,出现弹框如下:

选择Windows桌面 - > windows桌面向导

接着是这个界面:

选择动态链接库,空项目,再点击确定即可

接下来新建头文件和源文件

在这里添加一个头文件和源文件

头文件上右键,添加,新建项

 

 源文件同理添加

 

 完成之后,如图:

之后在.h和cpp中添加相关代码即可,头文件中添加导出函数接口,cpp具体实现

.H文件中类似代码如下:

#ifndef _MYDLL_H_
#define _MYDLL_H_
 
 
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
 
 
#ifdef __cplusplus
extern "C" {
#endif
 
    MYDLL_API int Add(int a, int b);
 
#ifdef __cplusplus
}
#endif
 
#endif //_MYDLL_H_

CPP中类似代码如下:

#include "mydll.h"
 
int Addin(int a, int b)
{
    return a+b;
}

项目属性方面也需要修改:

项目属性,C / C ++,预处理器添加

_AFXDLL
_AFXEXT
MYDLL_EXPORTS

预处理这里,可能各有不同,大家可根据自己的编译情况,自由添加。

另外个人还有一些习惯,习惯如下配置项目属性:

之后坐一些编译,可以看见编译出来了DLL文件

但是看不到lib文件

如果需要导出LIB文件,我们需要做一些操作:

在项目上右键,添加,新建项;
选择代码项,模块定义文件,DEF文件项

 

之后在编译,就可以看见的lib文件了

DEF文件内可如下写代码:

  1.  
    LIBRARY "mydll"
  2.  
    EXPORTS
  3.  
    Add @1

到这里添加动态库就结束了

假设我们现在生成一个动态库mydll

有头文件和源文件,mydll.h,mydll.cpp,该项目中mydll.h中没有内容,我们可以将它去除

把 上一篇生成的com_jni_HelloWorld.h  放到我们的工程目录下,并导入工程mydll中

如下所示:

 

 

接着是下一步操作

在mydll.cpp中实现那个接口,打印helloworld

#include "com_jni_HelloWorld.h"
 
 
JNIEXPORT void JNICALL Java_com_jni_HelloWorld_displayHelloWorld(JNIEnv *, jobject)
{
    printf("Hello World!\n");
}

之后编译,会报错,需要引入两个头文件,jni_md.h  和 jni.h,这两个是jni依赖的文件,依次在我们安装jdk时候的两个目录文件夹下,我这边的是这个目录

C:\Java\jdk-10.0.2\include\win32 

C:\Java\jdk-10.0.2\include   

将这两个目录附件包含目录到工程里面去,如下操作

注意上方有win32 和x64之分,如果你的eclipse是64位的,将不能使用32位的dll。

编译工程,得到一个64位,mydll.dll文件。

之后把这个dll文件拷贝到 JRE安装路径下的bin文件夹内,运行java程序即可。结果如下:

 

 这样完成了java通过jni调用C++动态库的过程,朋友们可通过上下两篇实现该功能

posted @ 2021-04-10 14:24  俊秀杰哥  阅读(464)  评论(0编辑  收藏  举报