美文网首页
Java调用go编译后的so或dll文件

Java调用go编译后的so或dll文件

作者: 清蒸三文鱼_ | 来源:发表于2024-05-06 16:26 被阅读0次

概述

gojee是用go语言编写的json结果提取工具, 其实JsonPath也能实现该功能, 这里仅用作学习记录

步骤

  1. 改写项目中的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))
}
  1. 在main.go文件所在目录执行go build -buildmode=c-shared -o go_jee.so, 执行完成后有一个.h和.so的文件

    如果是windows则执行go build -buildmode=c-shared -o go_jee.dll
  2. 编写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

相关文章

  • 安卓小知识点

    1、.so文件:安卓系统的可调用文件,类似windows里面的.dll。当然也可能是参与编译的文件

  • go编译dll给python调用

    go 编译成dll动态库 将生成的dll拷贝到python目录下 python调用代码

  • Python调用C++dll (window平台)

    注:python在linux操作系统下调用so文件,再windows下调用dll库注:生成dll库需要为relea...

  • C# 结合 Golang 开发

    1. 实现方式与语法形式 基本方式:将 Go 程序编译成 DLL 供 C# 调用。 1.1 Go代码 注意:代码中...

  • [NodeJs] 调用Go dll文件

    GO 步骤 设置编译环境为64位 GOARCH=amd64 ,如果想设置为32位 GOARCH=386需要生成动态...

  • jar包

    jar是java的发布形式,类似于windows的.dll,.exe文件和linux的.so,.a文件等。类比我们...

  • 动态编译基础

    一. 将函数或方法放在文本文件或dll文件或字符串中,可以修改添加后,直接使用主程序调用改变后的功能。(把方法和主...

  • Android NDK Jni学习使用(一)

    jni 编译三种方法 纯源码编译 写头文件,提供.a文件 编译 jni中调用so文件 编译 1. 创建工程 创建一...

  • GO 调用 DLL 类库

    最近一个项目需要用到Go调用C++的DLL类库 这里记录一下坑 DLL 原型 GO调用DLL 执行结果 坑 一开始...

  • golang plugin小谈

    在1.8之前,如果我们想用第三方的库,只能获取到源码才可以,而不能使用编译后的代码,比如jar、dll、so文件。...

网友评论

      本文标题:Java调用go编译后的so或dll文件

      本文链接:https://www.haomeiwen.com/subject/wywlfjtx.html