• 《Android进阶》之第一篇 在Java中调用C库函数


    在Java代码中通过JNI调用C函数的步骤如下:

    第一步:编写Java代码

     1 class HelloJNI{
     2     native void printHello();
     3     native void printString(String str);
     4     
     5     static {System.loadLibrary("hellojni");}
     6     
     7     public static void main(String args[]) {
     8         HelloJNI myJNI = new HelloJNI();
     9         
    10         myJNI.printHello();
    11         myJNI.printString("Hello World from c fun");
    12         
    13     }
    14     
    15 }

    第二步: 编译Java代码

        javac HelloJNI.java   生成HelloJNI.class文件

    第三步: 生成C语言头文件

        javah HelloJNI   生成HelloJNI.h头文件    

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloJNI */
    
    #ifndef _Included_HelloJNI
    #define _Included_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     HelloJNI
     * Method:    printHello
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloJNI_printHello
      (JNIEnv *, jobject);
    
    /*
     * Class:     HelloJNI
     * Method:    printString
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_HelloJNI_printString
      (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    第四步: 编写C代码

      要注意c代码必须得依照上面头文件的方式编写,和普通的c函数有区别

     1 #include"HelloJNI.h"
     2 #include<stdio.h>
     3 
     4 JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj) {
     5     printf("Hello World!
    ");
     6     return;
     7 }
     8 
     9 JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv * env, jobject obj, jstring string) {
    10     const char *str = (*env)->GetStringUTFChars(env,string,0);
    11     printf("%s!
    ",str);
    12     return;
    13 }

    第五步: 生成C共享库

       CodeBlocks下:

       File - New - Project - Shared library - Go

         因为HelloJNI.h中有这样的一句#include <jni.h>,标准的库文件下是没有这个文件的,但这个文件可以在JDK的安装目录下面找到

         

    为了能够顺利编译,需要把相应文件复制到C编译器的头文件存放处,像下面这样:

        

    编译生成C共享库文件:

        

    不过CodeBlocks默认生成的文件前面加了前缀lib,需要手动去掉,但运行是还是出了问题:

    1 D:hixinC>java HelloJNI
    2 Exception in thread "main" java.lang.UnsatisfiedLinkError: D:hixinChellojni.d
    3 ll: Can't load IA 32-bit .dll on a AMD 64-bit platform
    4         at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    5         at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    6         at java.lang.ClassLoader.loadLibrary(Unknown Source)
    7         at java.lang.Runtime.loadLibrary0(Unknown Source)
    8         at java.lang.System.loadLibrary(Unknown Source)
    9         at HelloJNI.<clinit>(HelloJNI.java:5)

    大意是生成的dll不是64位的,看了网上最新版的vs似乎是可以生成64位dll,算啦不纠结这个啦

  • 相关阅读:
    真的简单,文本文件逐行处理–用java8 Stream流的方式
    架构师最常使用的5种架构模式及其适用场景分析
    静态集成腾讯TBS X5内核WebView,从微信提取新版30M浏览器内核打包进apk
    redis入门指南(六)—— 集群
    波士顿动力狗 SPOT 权威购买指北
    Boolean源码解剖学
    SpringBoot+Mybatis整合出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)的解决
    linux实现shell脚本监控磁盘内存达到阈值时清理catalina.out日志
    【日志】新版日志技术
    【日志】经典日志框架
  • 原文地址:https://www.cnblogs.com/hixin/p/4379398.html
Copyright © 2020-2023  润新知