C / C++

先定义 Java native 接口:

package jni;

/**
 * @author syf
 * @date 2024/2/6
 **/
public class JniMath {

    static {
        System.load("/tmp/libzichecpp.so");
        System.load("/tmp/libzichego.so");
    }

    public static native long multiply(long x, long y);

    public static native long multiplygo(long x, long y);

    public static void main(String[] args) {
        System.out.println(JniMath.multiply(12345, 67890));
        System.out.println(JniMath.multiplygo(12345, 67890));
    }
}

javah生成关联的头文件

javah jni.JniMath

生成的jni_JniMath.h

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

#ifndef _Included_jni_JniMath
#define _Included_jni_JniMath
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_JniMath
 * Method:    multiply
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_jni_JniMath_multiply
  (JNIEnv *, jclass, jlong, jlong);

#ifdef __cplusplus
}
#endif
#endif

编写代码实现头文件中定义的函数:

#include "jni_JniMath.h"

JNIEXPORT jlong JNICALL Java_jni_JniMath_multiply
  (JNIEnv * env, jclass clazz, jlong argX, jlong argY) {

  return argX * argY;
}

编译 cpp,这里 JAVA_HOME 的头文件目录换成你的系统环境对应的

gcc -shared -fPIC -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin src/jni/jni_JniMath.c -o /tmp/libzichecpp.so

调用见 Java 部分的代码,不重复了

Golang

golang 从 1.5 版本开始支持 c-shared 模式编译,可以作为动态链接库调用

同样这里注释中cgo引入的CFLAG,头文件目录换成你的系统环境对应目录

package main

// #cgo CFLAGS: -I/Users/syf/opt/zulu-jdk-8/include
// #cgo CFLAGS: -I/Users/syf/opt/zulu-jdk-8/include/darwin
// #include <jni.h>
import "C"

//export Java_jni_JniMath_multiplygo
func Java_jni_JniMath_multiplygo(env *C.JNIEnv, clazz C.jclass, x C.jlong, y C.jlong) C.jlong {
    return x * y
}

// main function is required, don't know why!
func main() {} // a dummy function

编译:

go build -buildmode=c-shared -o /tmp/libzichego.so src/jni/jni_math.go

调用见 Java 部分的代码,不重复了

标签: cpp, java, c, golang

添加新评论