• Java小题,通过JNI调用本地C++共享库中的对应方法实现杨辉三角的绘制


    1.在Eclipse中配置Javah,配置如下

    位置是你javah.exe在你电脑磁盘上的路径

    位置:C:\Program Files\Java\jdk1.8.0_112\bin\javah.exe

    工作目录:${project_loc}/src

    自变量:-classpath .;./classes -d  "${project_loc}/jni" -jni ${java_type_name}


    2.创建一个java文件

     1 package experience5;
     2 
     3 public class NewNineToNine {
     4     public native void showInfo();
     5     static{
     6         System.loadLibrary("sy5-1");
     7     }
     8     public static void main(String[] args) {
     9         // TODO Auto-generated method stub
    10         NewNineToNine obj = new NewNineToNine();
    11         obj.showInfo();
    12     }
    13 
    14 }
    15  

    注意导入动态链接库不需要加后缀名

    将要用C++或C语言实现的方法设置成native类型


     3.选择要通过javah生成的类

    (需要点击一下吧,不然会报错:Launching javah has encountered a problem.The selected resourse does not resolve to a Java element

    或者Launching javah has encountered a problem.Variable references empty selection :${project_loc}

    只要点击了就好,个人觉得是这样哇》。《)

    然后点击运行

    这样就会在工程文件夹里生成一个jni的文件夹:

    在jni包里面生成了“experience5_NewNineToNine.h”


    4.编写一个C++文件,我用的是猥琐死丢丢2013,选择win32控制台程序,创建一个空白的 dll动态链接库 

    复制之前生成的“experience5_NewNineToNine.h“文件,

    和C:\Program Files (x86)\Java\jdk1.8.0_151\include目录下的jni.h文件

    ,以及C:\Program Files (x86)\Java\jdk1.8.0_151\include\win32目录下的jni_md.h文件放到和test.cpp同目录下

    =======================

    “experience5_NewNineToNine.h”文件:注意javah编译出的头文件打开之后显示的是#include<jni.h>因为我们要引入jdk下的 jni.h文件,所以要用双引号

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include "jni.h"
    /* Header for class experience5_NewNineToNine */
    
    #ifndef _Included_experience5_NewNineToNine
    #define _Included_experience5_NewNineToNine
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     experience5_NewNineToNine
     * Method:    showInfo
     * Signature: ()
     */
    JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    在源文件中创建一个test.cpp
    JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo
      (JNIEnv *, jobject);
    就是在javah生成的头文件中声明的方法,我们需要在test.cpp中把这个方法实现
    这些代码没优化,只到了能用的程度
    
    test.cpp:
    
     1 #include<iostream>
     2 #include"experience5_NewNineToNine.h"
     3 using namespace std;
     4 JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo(JNIEnv *env, jobject obj)
     5 {
     6     int a[11][11];
     7     for (int i = 1; i <= 10; i++) {
     8         a[i][1] = 1;
     9         a[i][i] = 1;
    10         for (int j = 2; j<i; j++) {
    11             a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
    12         }
    13 
    14         if (i>1) {
    15             for (int z = 0; z < (10 - i); z++) {
    16                 printf("  ");
    17 
    18             }
    19             for (int j = 1; j <= i; j++) {
    20                 cout << "   " << a[i][j];
    21             }
    22         }
    23         else    cout << "    " << a[1][1] << endl;
    24 
    25         cout << endl;
    26 
    27     }
    28 }

    .要在java中输出的内容就在test.cpp中的

     JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo(JNIEnv *env, jobject obj)方法体中实现
    然后直接编译运行过,会提示不能运行.dll文件,那么成功生成sy5-1.dll

     

    ==================
    然后还没完:
      让java程序成功调用sy5-1.dll有两种方法,自然有一种比较烦
        1.复制sy5-1.dll到系统的C:\Windows\System32目录下,默认环境变量有这个
        2.配置环境变量指向动态链接库所在的路径(这种表达我也不知道对不对,意思到了就好0.0) 

    配置好了就不用一次一次复制了,

    
    ==================
    最后一步:
        重启eclipse,编译运行。结果如下:

    
    发生的问题:
      1.抛出了java.lang.UnsatisfiedLinkError异常: no sy1 in java.library.path,程序没找到.dll文件,放对位置就没毛病了
      2.can't load IA 32-bit .dll on a AMD 64-bit platform错误,参考网上回答,最后我用了一个32位的JDK然后妥了;
        然后在StackOverflow里有个回答:https://stackoverflow.com/questions/8113080/cant-load-ia-32-bit-dll-on-a-amd-64-bit-platform
        里面是用cmd编译运行,有点迷,所以干脆下个32位JDK一了百了
      3.溜了溜了

    本文来自博客园,作者:你啊347,转载请注明原文链接:https://www.cnblogs.com/LinKinSJ/p/7853813.html

  • 相关阅读:
    一个简单的反反爬~
    查缺补漏 -- python 之 and or的优先级
    从今天开始看《Redis深度历险》--HyperLogLog
    从今天开始看《Redis深度历险》--位图
    从今天开始看《Redis深度历险》--延时队列
    从今天开始看《Redis深度历险》--分布式锁
    redis之set【官方文档搬运+翻译】
    从今天开始看《Redis深度历险》--基础
    collections模块学习之namedtuple
    元组赋值谜题
  • 原文地址:https://www.cnblogs.com/LinKinSJ/p/7853813.html
Copyright © 2020-2023  润新知