加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

从golang程序中执行另一个go程序

发布时间:2020-12-16 09:22:34 所属栏目:大数据 来源:网络整理
导读:我想从另一个go程序中执行另一个go程序并给它args,如下所示: package mainfunc main() { //here I want to call a specific go file,e.g. test.go with args} test.go package mainfunc main(x int) { //do stuff with x} 我不想发送一个int作为arg,但像htt
我想从另一个go程序中执行另一个go程序并给它args,如下所示:

package main
func main() {
  //here I want to call a specific go file,e.g. test.go with args
}

test.go

package main
func main(x int) {
  //do stuff with x
}

我不想发送一个int作为arg,但像http.ResponseWriter

我想到的解决方案,但它不会很好:

>使用gob将http.ResponseWriter转换为字符串
>从test.go读一行
>将字符串发送到test.go

谢谢你的回答:D

解决方法

有许多方法可以实现这种互操作性:
1-如果你有双方的源文件,我建议使用标准的golang包(Lib)调用,而不是互操作性.

2-使用“os / exec”:如果你没有源码,而你只有二进制,
?或者您可以通过文件或文本args传递args:

你可以通过这样的args:

package main

import (
    "fmt"
    "os"
)

func main() {

    fmt.Println(os.Args[0]) // fileNameAndPath
}

或使用“flag”std lib:

// flags.exe -h
package main

import (
    "flag"
    "fmt"
)

func main() {
    namePtr := flag.String("name","AR","name")
    agePtr := flag.Int("age",3700,"age")
    flag.Parse()
    fmt.Println(*namePtr,*agePtr) //AR 3700
}

/*
Usage of flags.exe:
  -age int
        age (default 3700)
  -name string
        name (default "AR")
*/

这将提供-h的帮助.
你可以像这样调用另一个二进制程序或golang编译器:

package main

import (
    "log"
    "os/exec"
)

func main() {
    cmnd := exec.Command("main.exe","arg")
    //cmnd.Run() // and wait
    cmnd.Start()
    log.Println("log")
}

3-另一种方法是使用stdin / stdout调用外部程序.
通过这种方式,您可以通过stdin / out发送二进制数据:
这里文件“a”调用二进制文件“b”并通过stdin / stdout发送和接收:
这是我的转换:
http://erlang.org/doc/tutorial/c_port.html
(你可以使用os命名管道)
档案a:

// a
package main

import (
    "fmt"
    "log"
    "os/exec"
    "runtime"
    "time"
)

var cout chan []byte = make(chan []byte)
var cin chan []byte = make(chan []byte)
var exit chan bool = make(chan bool)

func Foo(x byte) byte { return call_port([]byte{1,x}) }
func Bar(y byte) byte { return call_port([]byte{2,y}) }
func Exit() byte      { return call_port([]byte{0,0}) }
func call_port(s []byte) byte {
    cout <- s
    s = <-cin
    return s[1]
}

func start() {
    fmt.Println("start")
    cmd := exec.Command("../b/b")
    stdin,err := cmd.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }
    stdout,err2 := cmd.StdoutPipe()
    if err2 != nil {
        log.Fatal(err2)
    }
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    defer stdin.Close()
    defer stdout.Close()
    for {
        select {
        case s := <-cout:
            stdin.Write(s)
            buf := make([]byte,2)
            runtime.Gosched()
            time.Sleep(100 * time.Millisecond)
            stdout.Read(buf)
            cin <- buf
        case b := <-exit:
            if b {
                fmt.Printf("Exit")
                return //os.Exit(0)
            }
        }
    }
}
func main() {
    go start()
    runtime.Gosched()
    fmt.Println("30+1=",Foo(30)) //30+1= 31
    fmt.Println("2*40=",Bar(40)) //2*40= 80
    Exit()
    exit <- true
}

文件b:

// b
package main

import (
    "log"
    "os"
)

func foo(x byte) byte { return x + 1 }
func bar(y byte) byte { return y * 2 }

func ReadByte() byte {
    b1 := make([]byte,1)
    for {
        n,_ := os.Stdin.Read(b1)
        if n == 1 {
            return b1[0]
        }
    }
}
func WriteByte(b byte) {
    b1 := []byte{b}
    for {
        n,_ := os.Stdout.Write(b1)
        if n == 1 {
            return
        }
    }
}
func main() {
    var res byte
    for {
        fn := ReadByte()
        log.Println("fn=",fn)
        arg := ReadByte()
        log.Println("arg=",arg)
        if fn == 1 {
            res = foo(arg)
        } else if fn == 2 {
            res = bar(arg)
        } else if fn == 0 {
            return //exit
        } else {
            res = fn //echo
        }
        WriteByte(1)
        WriteByte(res)
    }
}

4 – 另一种方法是使用“net / rpc”,这是从另一个程序调用另一个函数的最佳方法.
样品:

// rpc
package main

import (
    "fmt"
    "net"
    "net/rpc"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

type Server struct{}

func (this *Server) Add(u [2]int64,reply *int64) error {
    *reply = u[0] + u[1]
    return nil
}

func server() {
    fmt.Println("server: Hi")
    rpc.Register(new(Server))
    ln,err := net.Listen("tcp","127.0.0.1:12345")
    if err != nil {
        fmt.Println(err)
        return
    }
    for {
        c,err := ln.Accept()
        if err != nil {
            continue
        }
        go rpc.ServeConn(c)
    }
}

func client() {
    wg.Add(1)
    c,err := rpc.Dial("tcp","127.0.0.1:12345")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Connected...")
    var result int64
    err = c.Call("Server.Add",[2]int64{10,20},&result)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Server.Add(10,20) =",result)
    }
    wg.Done()
}

func main() {
    go server()
    runtime.Gosched()
    go client()
    runtime.Gosched()
    wg.Wait()
    fmt.Println("Bye")
}

/*output:
server: Hi
Connected...
Server.Add(10,20) = 30
Bye
*/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读