概述
gojee是用go语言编写的json结果提取工具, 其实JsonPath也能实现该功能, 这里仅用作学习记录
步骤
- 改写项目中的main.go文件, 主要的变化是加入了
import "C"
和将main方法改为了func run(msg *C.char,exp *C.char)
, 方法前必须加上export
, 且入参和出参的类型需要为C对应的类型, 否则参数传递会无效
package main
import (
"encoding/json"
"fmt"
"github.com/nytlabs/gojee"
"os"
"C"
)
var info = `jee 0.1.1`
//export main
func main() {}
//export run
func run(msg *C.char,exp *C.char) *C.char{
var umsg jee.BMsg
l, err := jee.Lexer(C.GoString(exp))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
tree, err := jee.Parser(l)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = json.Unmarshal([]byte(C.GoString(msg)), &umsg)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
result, err := jee.Eval(tree, umsg)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
r, err := json.MarshalIndent(result, "", " ")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
//fmt.Println(string(r))
return C.CString(string(r))
}
- 在main.go文件所在目录执行
go build -buildmode=c-shared -o go_jee.so
, 执行完成后有一个.h和.so的文件
如果是windows则执行go build -buildmode=c-shared -o go_jee.dll
- 编写java程序, 打包成可运行的jar包, 执行命令
java -jar jna-demo.jar '{"name":123}' .name
- pom.xml
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
- interface
public interface GoJee extends Library {
GoJee INSTANCE = Native.loadLibrary("/root/gojee-master/jee/go_jee.so", GoJee.class);
String run(String msg,String exp);
}
- main
public class Main {
public static void main(String[] args) {
System.out.println(GoJee.INSTANCE.run(args[0],args[1]));
}
}
-
.h文件
-
执行结果
windows下编译成dll
背景
尝试用过Cygwin, 安装的东西有点多需要手动选择gcc相关依赖, 安装完之后编译报错gcc_libinit_windows.c: In function '_cgo_beginthread'
, 改用MinGW-w64后编译正常, mingw从github下载后, 再配置以下环境变量的path即可, 不需要其他复杂的操作, 配置简单. 参考文章: Windows下MinGW-w64的安装.
步骤
-
mingw github下载, windows系统版本较新的话可用ucrt版本
- 下载上面文件后解压, 配置环境变量. 命令行验证
gcc -v
- go env -w CGO_ENABLED=1, 然后执行
go env -w CGO_ENABLED=1
其他
- go项目依赖离线安装, 将GOPROXY改为本地目录,
go env
可查看, 将可联网机器的pkg/mod/cache/download/
下的文件copy过来, 同时注意go.sum和go.mod保持一致
修改命令:go env -w GOPROXY=file:///download
- go项目源码导入, 以gojee为例, 执行完之后会生成go.mod, 相关的依赖也会下载下来
go mod init jee -> go mod tidy