zoukankan      html  css  js  c++  java
  • 《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,算啦不纠结这个啦

  • 相关阅读:
    mysql设置外网访问
    c# 导出excel的两种常见方法
    mysql记录
    nginx配置文件nginx.conf简单介绍
    nginx编译安装之-./configure 参数详解
    Springboot中Filter的使用
    Spring Boot中@ConditionalOnProperty使用详解
    spring boot2 配置 FastJsonHttpMessageConverter 不起作用
    springBoot yaml属性配置文件使用详解
    Eclipse离线安装Java Decompiler插件(反编译)
  • 原文地址:https://www.cnblogs.com/hixin/p/4379398.html
Copyright © 2011-2022 走看看