3 回答

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊
有很多方法可以實(shí)現(xiàn)互操作性:
1- 如果您有雙方的源文件,我建議使用標(biāo)準(zhǔn)的 golang 包 (Lib) 調(diào)用,而不是互操作性。
2-使用“os/exec”:如果您沒有源代碼,并且只有二進(jìn)制文件,或者您可以通過文件或文本參數(shù)傳遞參數(shù):
你可以像這樣傳遞參數(shù):
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args[0]) // fileNameAndPath
}
或使用“標(biāo)志”標(biāo)準(zhǔn)庫(kù):
// 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 的幫助。
您可以像這樣調(diào)用另一個(gè)二進(jìn)制程序或 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-另一種方法是使用標(biāo)準(zhǔn)輸入/標(biāo)準(zhǔn)輸出調(diào)用外部程序。
這樣,您可以通過標(biāo)準(zhǔn)輸入/輸出發(fā)送二進(jìn)制數(shù)據(jù):
這里文件“a”調(diào)用二進(jìn)制文件“b”并通過標(biāo)準(zhǔn)輸入/標(biāo)準(zhǔn)輸出發(fā)送和接收:
這是我的轉(zhuǎn)換:
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
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”,這是從另一個(gè)程序調(diào)用另一個(gè)函數(shù)的最佳方式。
樣本:
// 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
*/

TA貢獻(xiàn)1911條經(jīng)驗(yàn) 獲得超7個(gè)贊
使用os/exec,您可以像這樣調(diào)用 go 編譯器:
output, err := exec.Command("go", "run", "/file/path/to/open").Output()
if err == nil {
w.Write(output) // write the output with ResponseWriter
}
Go 不會(huì)將參數(shù)傳遞給程序main,例如func main(x int). 在 Go 中執(zhí)行此操作的方法是使用os.Args.
在我看來,您正在嘗試在 Go 中使用 PHP 概念,結(jié)果不會(huì)很好。相反,您應(yīng)該使用模板和靜態(tài)文件來實(shí)現(xiàn)動(dòng)態(tài)網(wǎng)站。檢查包裹text/template。

TA貢獻(xiàn)1813條經(jīng)驗(yàn) 獲得超2個(gè)贊
為要從另一個(gè)文件運(yùn)行的包創(chuàng)建一個(gè)可執(zhí)行文件。提供要在其中運(yùn)行的文件的相對(duì)路徑exec.Command。例如:
文件 A
package a
import "fmt"
func main(){
for i:=0;i<10;i++{
fmt.Println(fmt.Sprintf("Process: %d", i))
}
}
為上述文件創(chuàng)建一個(gè)二進(jìn)制/可執(zhí)行文件。該文件將位于包內(nèi),因此請(qǐng)前往包并運(yùn)行可執(zhí)行文件。
go build github.com/user/a/a.go // or whatever be your GOPATH for executables to create a binary file
下面是linux系統(tǒng)中二進(jìn)制文件的情況。
文件 B
package b
import (
"fmt"
"os/exec"
)
func main(){
// come out of package b and then go inside package a to run the executable file as
cmd := exec.Command("../a/a.go")
if err := cmd.Run(); err != nil{
fmt.Println(err)
}
}
- 3 回答
- 0 關(guān)注
- 379 瀏覽
添加回答
舉報(bào)