java調用c++文件

網上有很多例子,參照着執行有時候相對路徑問題經常卡住了,實戰了一把通過後,特重新整理一份,供小白參考

首先需要有一個含有native方法的java類

vi /Users/mac/work/git/javademo/src/main/java/com/alioo/jni/JniDemo.java

package com.alioo.jni;

public class JniDemo {
    static {
        //System.setProperty("jna.library.path", "/Users/mac/work/git/javademo/target/classes/");
        //System.loadLibrary("libHello.dylib");
        //System.loadLibrary("Hello");


        System.load("/Users/mac/work/git/javademo/target/classes/libHello.dylib");

    }

    public native void printHello();

    public static void main(String[] args) {
        new JniDemo().printHello();
    }
}


編譯後對應的class文件如下

/Users/mac/work/git/javademo/target/classes/com/alioo/jni/JniDemo.class

通過javah命令來生成c++的.h文件

cd /Users/mac/work/git/javademo/target/classes
javah -jni com.alioo.jni.JniDemo


正常情況下可以生成如下文件com_alioo_jni_JniDemo.h

more /Users/mac/work/git/javademo/target/classes/com_alioo_jni_JniDemo.h


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_alioo_jni_JniDemo */

#ifndef _Included_com_alioo_jni_JniDemo
#define _Included_com_alioo_jni_JniDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_alioo_jni_JniDemo
 * Method:    printHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_alioo_jni_JniDemo_printHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


手寫c++實現類com_alioo_jni_JniDemo.cpp

備註:實現類com_alioo_jni_JniDemo.cpp跟com_alioo_jni_JniDemo.h在同一個目錄裏


vi /Users/mac/work/git/javademo/target/classes/com_alioo_jni_JniDemo.cpp

#include <iostream>
#include "com_alioo_jni_JniDemo.h"

JNIEXPORT void JNICALL Java_com_alioo_jni_JniDemo_printHello
  (JNIEnv *, jobject)
{
   printf("Hello, Java world!\n");
   return ;
}
int main(){

    return 1;
}

生成動態鏈接庫

備註:這一步你不能直接複製,需要改成你電腦中實際的jdk的路徑

cd /Users/mac/work/git/javademo/target/classes
g++ -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/ com_alioo_jni_JniDemo.cpp -o libHello.dylib

可能遇到的錯誤及解決辦法

‘jni.h’ file not found

$ g++ -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/ com_alioo_jni_JniDemo.cpp -o libHello.dylib

com_alioo_jni_JniDemo.cpp:1:10: fatal error: 'jni.h' file not found
#include "jni.h"
         ^~~~~~~
1 error generated.

解決辦法

$ sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/

可以看到生成了libHello.dylib


$ ll /Users/mac/work/git/javademo/target/classes
total 56
drwxr-xr-x   9 mac  staff    288 Nov  4 10:55 .
drwxr-xr-x  13 mac  staff    416 Oct 14 20:00 ..
-rw-r--r--   1 mac  staff    658 Oct 14 20:02 A.class
drwxr-xr-x   3 mac  staff     96 Oct 14 16:19 META-INF
drwxr-xr-x   3 mac  staff     96 Oct 14 16:49 com
-rw-r--r--   1 mac  staff    181 Nov  4 10:46 com_alioo_jni_JniDemo.cpp
-rw-r--r--   1 mac  staff    442 Nov  4 10:42 com_alioo_jni_JniDemo.h
drwxr-xr-x   3 mac  staff     96 Oct 14 16:49 java2
-rwxr-xr-x   1 mac  staff  12564 Nov  4 10:55 libHello.dylib

測試一把


$ pwd
/Users/mac/work/git/javademo/target/classes
$ java com.alioo.jni.JniDemo
Hello, Java world!

擴展

當然了,也可以用g++編譯成可執行程序,直接執行,但是這個已經與本文主題無關了,有興趣的也可以試試

cd /Users/mac/work/git/javademo/target/classes
g++ --std=c++11 com_alioo_jni_JniDemo.cpp -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/

上述命令如果沒有報錯的情況下會在當前目錄中生成一個可執行程序a.out

./a.out 
$ echo $?
 1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章