GO语言生成C动态库,再被链接成新动态库

目录

目标

测试代码

编译步骤

GO ----> 动态库

再封装成新动态库

编译生成可执行文件

尝试GO---->C静态库---->C动态库。


目标

如果想把GO语言实现的功能集成到C固定接口上,中间需要多加一次封装。

因为很难用GO直接封装已有实现,使得生产的动态库函数与目标接口一样的参数。GO语言生成的.h文件里函数的声明都是具有GO语言特性的变量类型。

测试代码

inter.go  函数实现

fdw.c    函数再封装

main.c  函数调用

root@ubuntu:/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*
root@ubuntu:/mnt/d/workspace/src/cktest# 
root@ubuntu:/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() {
}
root@ubuntu:/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;
}

root@ubuntu:/mnt/d/workspace/src/cktest# cat fdw.h
#ifndef __FDW_H__
#define __FDW_H__

int ExecForeignInsert(char *x);

#endif
root@ubuntu:/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

root@ubuntu:/mnt/d/workspace/src/cktest# go build -o libinter.so -buildmode=c-shared inter.go
root@ubuntu:/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

root@ubuntu:/mnt/d/workspace/src/cktest# gcc fdw.c -fPIC -shared -o libfdw.so -L. -linter
root@ubuntu:/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

root@ubuntu:/mnt/d/workspace/src/cktest# gcc main.c -o main -L. -lfdw
root@ubuntu:/mnt/d/workspace/src/cktest# ./main
Write to test

Go语言里的writeto函数被成功执行到。

尝试GO---->C静态库---->C动态库。

root@ubuntu:/mnt/d/workspace/src/cktest# go build -o inter.a -buildmode=c-archive inter.go
root@ubuntu:/mnt/d/workspace/src/cktest# ls
fdw.c  fdw.h  inter.a  inter.go  inter.h  main.c  make.sh

root@ubuntu:/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;
}

.再编译动态库,报错。暂没找到解决办法。

root@ubuntu:/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语言的其他数据库了。

猜你喜欢

转载自blog.csdn.net/jacicson1987/article/details/82893692