目录
目标
如果想把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语言的其他数据库了。