zoukankan      html  css  js  c++  java
  • jni调用

    花了三天时间,终于把这个环境和实现都弄通了一遍。

    先来个总纲:

    准备工作:jdk环境,eclipse,gcc环境,cdt插件

    a.编写带有native声明的java类,

    b.编译java类

    c.用javah -jni生成头文件

    d.使用其他语言(c、c++)实现native method

    e.生成动态链接库

    考虑到自己很久没有接触vs和vc,此次实现jni使用eclipse的CDT插件,所以第一步是安装CDT插件,CDT插件的运行还依赖于系统的c、c++编译器,win7下一个不错的c编译器为MinGW,所以先下载安装配置MinGW,http://www.mingw.org/

     

    安装:全部选中

    添加环境变量:path里添加C:MinGWin

    ok,试一下有没有成功,win+r,cmd,gcc -v,如果出现如下图就表示可正常使用gcc编译器。

    下一步可以安装CDT了,打开eclipse,help,install new software,折腾吧,这里有点忘了,安装的时候可能会有冲突,安装完了就可以用file>new>c projet了。

    准备工作到这里就结束了,开始总纲中的步骤

    a.新建一个java项目,新建一个java类

    package lan;
    
    public class Test {
        public native void hello(); 
        static {
            System.out.println("Test...static...");
            System.loadLibrary("hello");
        }
        public static void main(String[] args) {
            new Test().hello();
        }
    
    }

    b.编译java类
    进入cmd命令行下lan目录

    javac lan/Test.java

    生成Test.class
    c.用javah -jni生成头文件

    javah -jni -cp . lan.Test

    解释一下这个命令:javah -jni 生成头文件,-cp . ,-cp是指明类搜索,.是指本目录,后面加上类名,要包名加类名写全。头文件出现在执行命令的路径下。lan_Test.h
    d.使用其他语言(c、c++)实现native method,File>new>c project,选择Shared Library Empty Project>MinGW GCC

    把刚刚javah生成的lan_Test.h头文件拷贝到这个项目中,

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

    可见这里有一个函数的声明,然后新建一个source文件,Test.c写入内容如下

    /*
     * Test.c
     *
     *  Created on: 2015-2-27
     *      Author: azul
     */
    #include <stdio.h>
    #include "lan_Test.h"
    
    JNIEXPORT void JNICALL Java_lan_Test_hello
      (JNIEnv *, jobject){
        printf("hello,world!hello,C!");
        return;
    }

    e.生成dll文件

    E:
    ew_workspaceCallTest>gcc -I "C:Javajdk1.7.0_51include" -I "C:Javajdk1.7.0_51includewin32"  -shared Test.c -o hello.dll
    Test.c: In function 'Java_lan_Test_hello':
    Test.c:11:3: error: parameter name omitted
       (JNIEnv *, jobject){
       ^
    Test.c:11:3: error: parameter name omitted

    结果有这个错误,是由于c和c++的区别造成的,将c源文件改为c++的,即将Test.c更名为Test.cpp,-I是为了将缺少的两样,jni.h和jni_md.hjava_home中的include和其下的win32包含进来。

    ok,dll文件生成,试一下运行java程序

    E:
    ew_workspaceTestsrclan>java -Djava.library.path="E:
    ew_workspaceCallTest"  -cp ../ lan.Test
    Test...static...
    Exception in thread "main" java.lang.UnsatisfiedLinkError: lan.Test.hello()V
            at lan.Test.hello(Native Method)
            at lan.Test.main(Test.java:10)
    
    E:
    ew_workspaceTestsrclan>

    说明程序运行了,可是链接出错了,查文档,看论坛,参考 http://bbs.csdn.net/topics/80272618 所说,应该是由于vc和gcc生成dll库的时候命名规则导致的函数名前缀"_"差异,重新生成dll文件

    E:
    ew_workspaceCallTest>gcc -I "C:Javajdk1.7.0_51include" -I "C:Javajdk1.7.0_51includewin32"  -shared Test.cpp -Wl,--kill-at -o hello.dll

    再次运行java程序

    E:
    ew_workspaceTestsrclan>java -Djava.library.path="E:
    ew_workspaceCallTest"  -cp ../ lan.Test
    Test...static...
    hello,world!hello,C!
    E:
    ew_workspaceTestsrclan>

    非常好,成功了。放在eclipse中用run运行一下,将dll文件放入项目中,

    运行结果如图:

    ok!成功,这里主要注意的几个问题是java运行程序时候寻路径的问题,提示找不到类的时候可以加上-cp,运行文件的时候用包名/类,运行类的时候用包名.类

    这个故事先告一段段落了。

  • 相关阅读:
    deepin系统安装php扩展(或者统信UOS系统)
    前后端分离项目,访问后端接口跨域问题解决办法
    python打乱一个文件行数据
    python获取文件行数
    SQL进阶
    方便下载书籍网站
    gpuz软件下载
    U盘制作-安装win10系统
    docker -Docker安装FileBrowser实现网页版文件管理器
    OCP 063中文考试题库(cuug内部资料)第44题
  • 原文地址:https://www.cnblogs.com/azul0906/p/4303721.html
Copyright © 2011-2022 走看看