Java调用Golang生成的动态库(dll,so)
柠檬信息技术有限公司
2018.07.13 17:32* 字数 863 阅读 327评论 2喜欢 0
0x01. 环境准备
A. GCC
在控制台中输入
gcc -v
如果提示命令未找到,那么说明你的计算机中还没有gcc,去安装一个吧,gcc官方网站:https://gcc.gnu.org/
如果从来没有安装过gcc的朋友可以直接安装win-build,可以帮你快速的安装
官方网站:http://mingw-w64.org/doku.php/download/win-builds
0x02. 编写go程序
我们这里只是编写一个简单的输出字符串的程序,接受一个字符串参数,然后将拼接成新的字符串并作为返回值返回,在这里,我们将文件命名为libhello.go
package main
import "C"
//export Sum
func Sum(a int, b int) int {
return a + b
}
func main() {
}
注意,即使是要编译成动态库,也要有main函数,上面的import “C”一定要有
而且一定要有注释
//export Sum
经测试,如果没有这个导出的DLL库中找不到对应的函数
0x03. 编译go程序
首先,将控制台的所在目录切换到go程序的所在目录,即libhello.go所在目录
A. Windows动态库
执行如下命令生成DLL动态链接库:
go build -buildmode=c-shared -o libhello.dll .\libhello.go
如果控制台没有报错,那么会在当前路径下生成libhello.dll文件
B. Linux/Unix/macOS动态库
执行如下命令生成SO动态库:
go build -buildmode=c-shared -o libhello.so .\libhello.go
0x04. 在java中调用
A. JNA的引用
Java调用Native的动态库有两种方式,JNI和JNA,JNA是Oracle最新推出的与Native交互的方式,具体介绍我就不多说了,引用百度百科的连接:https://baike.baidu.com/item/JNA/8637274?fr=aladdin ,有需要的朋友可以去看看。
在这里,我们使用JNA的方式,JNI的方式基本废弃,除非有特殊需要,在这里不多说,有需要可以联系我讨论。
新建Java工程,我使用的是Maven做包管理,所以直接引用JNA的依赖:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
如果你没有使用包管理工具,可以直接下载Jar文件引入,下载地址也贴一下吧,也是4.5.2版本的:
http://central.maven.org/maven2/net/java/dev/jna/jna/4.5.2/jna-4.5.2.jar
B. 创建接口
我们需要创建一个interface来映射DLL中的函数,之后我们可以通过interface的实例来访问DLL中的函数。
package cn.lemonit.robot.runner.executor;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface LibHello extends Library {
LibHello INSTANCE = (LibHello) Native.loadLibrary("E:/workspace/libhello", LibHello.class);
int Sum(int a, int b);
}
注意,Sum是函数名,一定要与Go中事先写好的函数名保持一致
Native.loadLibrary()的第一个参数是一个字符串,要加载的DLL的名称或全路径,后面不需要加.dll后缀。第二个参数为interface的名称。
C. 调用
我们新建一个App类,作为main方法的入口类,在main方法中不需要多余的操作,只需要调用即可,在这里我们调用Sum方法,同时传如1 , 2,可以看到控制台输出:3
package cn.lemonit.robot.runner.executor;
public class App {
public static void main(String[] args) {
System.out.println(LibHello.INSTANCE.Sum(1, 2));
}
}
0x05. 开始踩坑
未完待续
抱歉各位朋友,由于我这两天家里有事,还赶上驾校天天练车,所以没能一次性写完这篇文章,如果你在实验过程中发现你的参数是string类型的时候java无法调用,那么不用担心,等待我下次更新给你讲解哦!!!
ft_update_time2018-07-17 01:46