Java 呼叫 c++ 函數

最近課業需要查了一下,並且在 Mac 上弄出來。

第一步

先準備一個Sample1.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Sample1
{
    public native void func1();

    public static void main(String[] args)
    {
        Sample1 sample = new Sample1();
        System.load(args[0] + "/libsample.so"); // 絕對路徑
        sample.func1();
        return;
    }
}

然後

1
2
$ javac Sample1.java
$ javah Sample1

第二步

這時會發現除了Sample1.class以外,還有Sample1.h

打開後可以看到

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Sample1 */

#ifndef _Included_Sample1
#define _Included_Sample1
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Sample1
 * Method:    func1
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Sample1_func1
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

這些是javah自動依照Sample1.java生成的,原因是因為有一個native function

所以這時可以準備一個對應的cpp檔案和func1

1
2
3
4
5
6
7
#include <cstdio>
#include "Sample1.h"

JNIEXPORT void JNICALL Java_Sample1_func1(JNIEnv* jenv, jobject jobj){
    printf("ok\n");
    return;
}

第三步

這時後就要準備把Sample1.cpp做成libsample.so

1
2
$ g++ Sample1.cpp -I"/System/Library/Frameworks/JavaVM.framework/Headers" -c -fPIC
$ g++ Sample1.o -shared -o libsample.so

收工

1
$ java Sample1 `pwd`