1. 程式人生 > >GO語言生成C動態庫,再被連結成新動態庫

GO語言生成C動態庫,再被連結成新動態庫

目錄

目標

測試程式碼

編譯步驟

GO ----> 動態庫

再封裝成新動態庫

編譯生成可執行檔案

嘗試GO---->C靜態庫---->C動態庫。


目標

如果想把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語言的其他資料庫了。