GO語言生成C動態庫,再被連結成新動態庫
阿新 • • 發佈:2018-11-28
目錄
目標
如果想把GO語言實現的功能整合到C固定介面上,中間需要多加一次封裝。
因為很難用GO直接封裝已有實現,使得生產的動態庫函式與目標介面一樣的引數。GO語言生成的.h檔案裡函式的宣告都是具有GO語言特性的變數型別。
測試程式碼
inter.go 函式實現
fdw.c 函式再封裝
main.c 函式呼叫
[email protected] :/mnt/d/workspace/src/cktest# ll
total 0
drwxrwxrwx 1 ckun ckun 512 Sep 29 11:59 ./
drwxrwxrwx 1 ckun ckun 512 Sep 28 18:27 ../
-rwxrwxrwx 1 ckun ckun 258 Sep 29 11:48 fdw.c*
-rwxrwxrwx 1 ckun ckun 77 Sep 29 11:08 fdw.h*
-rwxrwxrwx 1 ckun ckun 215 Sep 29 11:47 inter.go*
-rwxrwxrwx 1 ckun ckun 95 Sep 29 11:06 main.c*
-rwxrwxrwx 1 ckun ckun 147 Sep 29 11:58 make.sh*
[email protected]:/mnt/d/workspace/src/cktest#
[email protected]:/mnt/d/workspace/src/cktest# cat inter.go
package main
import (
"C"
"fmt"
)
//export writeto
func writeto(str string) {
fmt.Println("Write to " + str)
}
//export readfrom
func readfrom(str string) {
fmt.Println("Read from " + str)
}
func main() {
}
[email protected]:/mnt/d/workspace/src/cktest# cat fdw.c
#include <stdio.h>
#include <string.h>
#include "fdw.h"
#include "libinter.h"
int ExecForeignInsert(char *x)
{
if (!x) {
printf("Para Error\n");
return -1;
}
GoString str;
str.p = x;
str.n = strlen(x);
writeto(str);
return 0;
}
[email protected]:/mnt/d/workspace/src/cktest# cat fdw.h
#ifndef __FDW_H__
#define __FDW_H__
int ExecForeignInsert(char *x);
#endif
[email protected]:/mnt/d/workspace/src/cktest# cat main.c
#include <stdio.h>
#include "fdw.h"
int main() {
ExecForeignInsert("test");
return 0;
}
編譯步驟
GO ----> 動態庫
go build -o libinter.so -buildmode=c-shared inter.go
生成.h和.so
[email protected]:/mnt/d/workspace/src/cktest# go build -o libinter.so -buildmode=c-shared inter.go
[email protected]:/mnt/d/workspace/src/cktest# ll *inter*
-rwxrwxrwx 1 ckun ckun 201 Sep 29 10:47 inter.go*
-rwxrwxrwx 1 ckun ckun 1318 Sep 29 10:52 libinter.h*
-rwxrwxrwx 1 ckun ckun 3173640 Sep 29 10:52 libinter.so*
再封裝成新動態庫
gcc fdw.c -fPIC -shared -o libfdw.so -L. -linter
[email protected]:/mnt/d/workspace/src/cktest# gcc fdw.c -fPIC -shared -o libfdw.so -L. -linter
[email protected]:/mnt/d/workspace/src/cktest# ll *fdw*
-rwxrwxrwx 1 ckun ckun 250 Sep 29 10:49 fdw.c*
-rwxrwxrwx 1 ckun ckun 77 Sep 29 10:49 fdw.h*
-rwxrwxrwx 1 ckun ckun 8072 Sep 29 10:54 libfdw.so*
編譯生成可執行檔案
gcc main.c -o main -L. -lfdw
[email protected]:/mnt/d/workspace/src/cktest# gcc main.c -o main -L. -lfdw
[email protected]:/mnt/d/workspace/src/cktest# ./main
Write to test
Go語言裡的writeto函式被成功執行到。
嘗試GO---->C靜態庫---->C動態庫。
[email protected]:/mnt/d/workspace/src/cktest# go build -o inter.a -buildmode=c-archive inter.go
[email protected]:/mnt/d/workspace/src/cktest# ls
fdw.c fdw.h inter.a inter.go inter.h main.c make.sh
[email protected]:/mnt/d/workspace/src/cktest# vim fdw.c
#include <stdio.h>
#include <string.h>
#include "fdw.h"
#include "inter.h" //修改標頭檔案名
int ExecForeignInsert(char *x)
{
if (!x) {
printf("Para Error\n");
return -1;
}
GoString str;
str.p = x;
str.n = strlen(x);
writeto(str);
return 0;
}
.再編譯動態庫,報錯。暫沒找到解決辦法。
[email protected]:/mnt/d/workspace/src/cktest# gcc fdw.c -fPIC -shared -o libfdw.so -L. inter.a
/usr/bin/ld: inter.a(go.o): relocation R_X86_64_TPOFF32 against `runtime.tlsg' can not be used when making a shared object; recompile with -fPIC
inter.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
GO--->靜態庫 ---X--->動態庫 是失敗的。
小結
這次編譯測試,PG FDW可以整合GO語言的其他資料庫了。