• java中native的用法


    java中native的用法

    public static native void  java.lang.System.arraycopy(Object, int, Object, int, int)方法竟然是native的,

    查询了一下java中native的用法,找到如下文章,

    学习了:https://www.cnblogs.com/b3051/p/7484501.html 

    但是,自己手痒,写了一下,结果,填了几个坑;

    1,javah 之前没有使用过,用起来还算可以,中规中矩;

    2,编写C文件也还可以;随便写,结果就挖了一个坑;

    3,使用cl编译有些问题,有些文章说要安装Visio Studio 20XX,

    学习了:http://blog.163.com/yuyang_tech/blog/static/2160500832013118112049372/

    决定使用vc6.0来做,

    下载地址:http://www.pc6.com/softview/SoftView_51072.html

    解压至D:pvc6VC98BIN,在添加到系统path中;

    后来发现我把D:pvc6COMMONMSDEV98BIN;D:pvc6VC98INCLUDE也加到路径里面了;忘记为啥了;

    出错1:

    D:JavagitworkspaceCodingin>CL.EXE -I%java_home%include -I%java_home%inclu
    dewin32 -LD JavaNativeImp.c -Fehello.dll
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
    
    JavaNativeImp.c
    D:Javajdk1.8.0_05includejni.h(39) : fatal error C1083: Cannot open include f
    ile: 'stdio.h': No such file or directory

    开始模拟 -I参数,

    CL.EXE -I%java_home%include -I%java_home%includewin32 -ID:pvc6VC98INCLUDE -LD JavaNativeImp.c -Fehello.dll

    出错2:

    D:JavagitworkspaceCodingin>CL.EXE -I%java_home%include -I%java_home%inclu
    dewin32 -ID:pvc6VC98INCLUDE -LD JavaNativeImp.c -Fehello.dll
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
    
    JavaNativeImp.c
    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
    
    /dll
    /implib:hello.lib
    /out:hello.dll
    JavaNativeImp.obj
    LINK : fatal error LNK1104: cannot open file "LIBCMT.lib"

    找不到参数可以加lib了,

    学习了:http://blog.csdn.net/cruise_h/article/details/29218407

    在我的电脑->属性->高级系统设置->环境变量->系统变量中新建系统变量LIB、INCLUDE并设置它们的值为:

    LIB:D:pvc6VC98LIB

    INCLUDE:%java_home%include;%java_home%includewin32;D:pvc6VC98INCLUDE

    这样直接输入:cl -LD JavaNativeImp.c -Fehello.dll就可以编译了;

    输出:

    D:JavagitworkspaceCodingin>cl -LD JavaNativeImp.c -Fehello.dll
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
    
    JavaNativeImp.c
    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
    
    /dll
    /implib:hello.lib
    /out:hello.dll
    JavaNativeImp.obj
       Creating library hello.lib and object hello.exp

    结果运行的时候报错;

    出错3:

    D:JavagitworkspaceCodingin>java com.stono.jvm.JavaNative
    Exception in thread "main" java.lang.UnsatisfiedLinkError: D:Javagitworkspace
    Codinginhello.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
            at java.lang.ClassLoader$NativeLibrary.load(Native Method)
            at java.lang.ClassLoader.loadLibrary0(Unknown Source)
            at java.lang.ClassLoader.loadLibrary(Unknown Source)
            at java.lang.Runtime.loadLibrary0(Unknown Source)
            at java.lang.System.loadLibrary(Unknown Source)
            at com.stono.jvm.JavaNative.<clinit>(JavaNative.java:6)

    因为在Eclipse中使用了64位的java,dll使用的是32位的;

    学习了:https://stackoverflow.com/questions/8113080/cant-load-ia-32-bit-dll-on-a-amd-64-bit-platform 只能把Java改成32位了;因为C语言64不熟悉;

    重新用EditPlus写了Java文件,用32位jdk编译;

    运行的时候报错,

    出错4:

    D:>d:javajdk1.6.0_12injava.exe JavaNative
    Exception in thread "main" java.lang.UnsatisfiedLinkError: JavaNative.hello(Ljav
    a/lang/String;)V
            at JavaNative.hello(Native Method)
            at JavaNative.main(JavaNative.java:7)

    最开始以为是dll文件是原来的java程序生成的,就又重头跑了一遍;就是先javah -jni xxx,然后写c文件,然后cl编译;

    结果还是出错4;

    学习了:https://www.cnblogs.com/cuglkb/p/5665882.html 这个方法没有测试;

    http://blog.csdn.net/missingu1314/article/details/12650725 用的是这个方法;

    主要是因为在dll中,可能xxx.h头文件中的接口名和xxx.cpp源文件中的实现函数名不一致导致的。

    源码:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class JavaNative */
    
    #ifndef _Included_JavaNative
    #define _Included_JavaNative
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     JavaNative
     * Method:    hello
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_JavaNative_hello
      (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    #include <jni.h>
    #include "JavaNative.h"
    #include <stdio.h>
    JNIEXPORT void JNICALL Java_JavaNative_hello(JNIEnv *env,jobject obj, jstring name){
        
        const char *str; 
        str = (*env)->GetStringUTFChars(env, name, NULL); 
        if (str == NULL) { 
            return; 
        } 
        
        printf("Hello World! %s 
    ", str );
        return;
    }

    C文件可以随便起名,但是方法必须和接口中的名字一样;

    然后就又是cl编译,然后java JavaNative就可以了;

    Java源码:

    public class JavaNative {
        public native void hello(String name);
        static{
            System.loadLibrary("hello");
        }
        public static void main(String[] args) {
            new JavaNative().hello("jni");
        }
    }
  • 相关阅读:
    娿
    我不知道啊
    Android怎么把引入的library库工程转换成jar包
    高斯消元入门和简单应用
    数论函数基本知识
    AC自动机入门和简单应用
    FFT和NTT
    同余系基本知识
    虚树学习笔记
    Windows常用快捷键和基本的Dos命令
  • 原文地址:https://www.cnblogs.com/stono/p/8213530.html
Copyright © 2020-2023  润新知