Go黑魔法之導出函數供C調用
go build 包含一個選項-buildmode可通過配置c-archive & c-shared兩種模式分別生成可供C調用的靜態 & 動態庫.
具體詳情可通過go help buildmode查看幫助.
示例
go 代碼
這是FastCGI unix socket 簡單示例, 響應FastCGI請求迴應”Hello World!”.
注意:
import “C” 與 “//export FCGI_run ” 爲必須配置,啓用export用於導出Library函數名稱;
package main
import (
"C"
"fmt"
"net"
"net/http"
"net/http/fcgi"
)
func handler(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, "Hello World!")
}
//export FCGI_run
func FCGI_run() {
l, err := net.Listen("unix", "/var/run/go-fcgi.sock")
if err != nil {
return
}
http.HandleFunc("/", handler)
fcgi.Serve(l, nil)
}
func main () {}
編譯動態庫
go build -a -v -buildmode=c-shared -o libfcgi_api.so fcgi_api.go
分別生成 fcgi_api.h & libfcgi_api.so.
C 代碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include "fcgi_api.h"
int main(int argc, char **argv)
{
FCGI_run();
return 0;
}
編譯
gcc fcgi_api_test.c -o fcgi_api_test -L./ -lfcgi_api -Wl,-rpath="\$ORIGIN/"
測試
nginx 配置
轉發FastCGI請求
...
server {
listen 80;
server_name example.com;
location / {
fastcgi_pass unix:/var/run/go-fcgi.sock;
include fastcgi_params;
}
}
...
啓動NGINX
nginx -c goapp.conf
FastCGI
./fcgi_api_test &
cURL 測試
curl -q -v http://example.com/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.12.1
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Date: Fri, 17 Aug 2018 04:05:19 GMT
<
* Connection #0 to host example.com left intact
Hello World!