运行 来自共享库的服务器

Running server from shared library

尝试运行来自共享库的服务器,所以我做了以下操作:

  1. 将 shahred 库编写为:
// server.go
package main

import (
    "fmt"
    "net/http"
)
import "C"

func hello(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "hello\n")
}
func headers(w http.ResponseWriter, req *http.Request) {
    for name, headers := range req.Header {
        for _, h := range headers {
            fmt.Fprintf(w, "%v: %v\n", name, h)
        }
    }
}
func main() {}

// export Run server
func Run(port string) {
    http.HandleFunc("/hello", hello)
    http.HandleFunc("/headers", headers)
    if err := http.ListenAndServe("localhost:"+port, nil); err == nil {
        fmt.Println("listening to 8090")
    } else {
        fmt.Println("ListenAndServe: ", err)
    }
}
  1. 将共享库编译为:
$ go build -buildmode c-shared -o server.so server.go
  1. 将调用共享库中Run函数的主文件写为:
//main.go
package main

/*
#cgo LDFLAGS: -ldl
#include <dlfcn.h>

void Run(char* port){}

*/
import "C"

func main() {
    // handle := C.dlopen(C.CString("server.so"), C.RTLD_LAZY)
    // C.dlsym(handle, C.CString("8090"))

    C.dlopen(C.CString("server.so"), C.RTLD_LAZY)
    C.run(C.CString("8090"))
}
  1. 运行 主文件为:
$ go run main.go

main函数直接终止了,srver还没运行在http://localhost:8090/hello

你为什么不把它分成一个 go 包(例如:包服务器)和导入这个包的主要应用程序:

yourproject/cmd/server/main.go

package main

import (
    "yourproject/internal/server"
)

func main() {
    srv := server.New()
    // ...
    port := "8443"
    // do some logic here

    srv.Run(port)
}

yourproject/internal/server/server.go

package server

import (
    "fmt"
    "net/http"
)
import "C"

type Server struct{}

func New() *Server {
    return &Server{}
}

func hello(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "hello\n")
}

func headers(w http.ResponseWriter, req *http.Request) {
    for name, headers := range req.Header {
        for _, h := range headers {
            fmt.Fprintf(w, "%v: %v\n", name, h)
        }
    }
}

// export Run server
func (s *Server) Run(port string) {
    http.HandleFunc("/hello", hello)
    http.HandleFunc("/headers", headers)
    if err := http.ListenAndServe("localhost:"+port, nil); err == nil {
        fmt.Println("listening to 8090")
    } else {
        fmt.Println("ListenAndServe: ", err)
    }
}