环境准备
安装gcc环境,gcc.gnu.org/
也可以直接安装win-build,sourceforge.net/projects/mi…
我使用的就是安装后者,选择这个包:
解压下载的安装包:
然后设置环境变量:
最后在系统变量Path后面追加如下:%MINGW_HOME%\bin
检查是否安装成功:
测试加法运算
编写如下go程序,取名go4Java.go
package main
import (
"fmt"
)
import "C"
//export Add
func Add(x, y int) int {
fmt.Printf("Go says: adding %v and %v\n", x, y)
return x + y
}
func main() {
}
然后编译该文件,生成动态库:
Windows:go build -buildmode=c-shared -o go4Java.dll .\go4Java.go
Linux:go build -buildmode=c-shared -o go4Java.so .\go4Java.go
JNA调用
新建Java工程,加入如下依赖:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
再创建一个接口来映射DLL中的函数,之后可以通过interface的实例来访问DLL中的函数。
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* @author: yuzp
* @date: 2023/01/11 14:43
* @Description: 描述
*/
public interface ITest extends Library {
ITest INSTANCE = (ITest) Native.loadLibrary("D:/workspace/go4Java", ITest.class);
int Add(int a, int b);
}
然后就可以使用单元测试来调用了:
@Test
void test() {
System.out.println(ITest.INSTANCE.Add(1,2));
}
字符串传参
字符串传参会麻烦一点,其实本质是两边String类型不能直接对应起来,下面是一个简单的对应关系:
先在Java端定义Go的字符串结构体:
import com.sun.jna.Structure;
import java.util.ArrayList;
import java.util.List;
/**
* @author: yuzp
* @date: 2023/01/11 9:49
* @Description: 描述
*/
public class GoString extends Structure {
public String str;
public long length;
public GoString() {
}
public GoString(String str) {
this.str = str;
this.length = str.length();
}
@Override
protected List<String> getFieldOrder() {
List<String> fields = new ArrayList<>();
fields.add("str");
fields.add("length");
return fields;
}
public static class ByValue extends GoString implements Structure.ByValue {
public ByValue() {
}
public ByValue(String str) {
super(str);
}
}
public static class ByReference extends GoString implements Structure.ByReference {
public ByReference() {
}
public ByReference(String str) {
super(str);
}
}
}
go端新增定义go的函数:
//export Str
func Str(msg string) *C.char {
return C.CString("hello : " + msg)
}
java端ITest新增如下接口:
String Str(GoString.ByValue msg);
采用如下方式来调用:
@Test
void test() {
System.out.println(ITest.INSTANCE.Str(new GoString.ByValue("world")));
}
参考: