golang “非主流”技巧 分享(1) --生成 c 可调用代码

2019-10-05 10:02:37 +08:00
 guonaihong

golang 得益与强大的生态,开发起来顺风顺水。c 语言作为老牌高性能语言,还是很多童鞋的最爱,但是开发效率是硬伤。假如要在 c 庞大的协议框架代码上改来该去,又或者要写个 c 网络通信的 sdk(提供 http 或者 websocket 协议)。有没有快速的方法搞定这些事情,这两个语言能不能摩擦出火花。还真的可以。。。请看下面的例子

导出字符串函数给 c 用

下面把 go 里面的 ReplaceAll 函数导出给 c 用。
函数上面的 export ReplaceStrAll 是必须的,告诉编译器,你要什么名字的 c 函数

package main

import (
    "strings"
)

import "C" 

//export ReplaceStrAll
func ReplaceStrAll(str *C.char, old *C.char, new *C.char) (rv *C.char) {

    s := C.GoString(str)
    oldStr := C.GoString(old)
    newStr := C.GoString(new)

    repRv := strings.Replace(s, oldStr, newStr, -1) 
    rv = C.CString(repRv)
    return
}

func main() {
}

env GOPATH=`pwd` go build -buildmode=c-archive -o replace.a replace.go
#include <stdio.h>
#include <stdlib.h>
#include "replace.h"

int main() {
	char * p = ReplaceStrAll("aaa hello world bbb hello world ccc hello world ddd", "hello world", "");
	printf("%s\n", p);
	free(p);
	return 0;
}

gcc -I .  use.c replace.a -Wall -lpthread

未完待续

由于要做饭,后面还有几个例子等有时间完善。

github

https://github.com/guonaihong/gout

3088 次点击
所在节点    Go 编程语言
5 条回复
bumz
2019-10-05 10:38:17 +08:00
好奇下,C 调用 Go 代码,那 Go 运行时咋办
banxi1988
2019-10-05 10:38:46 +08:00
这个编译出来的库体积大吗?
reus
2019-10-05 12:04:48 +08:00
@bumz go 运行时会初始化。而且只能有一个初始化,所以你想链接两个 .a,是不行的,因为两套运行时会导致符号冲突。所以使用场景限制是比较大的。
zjsxwc
2019-10-05 12:35:15 +08:00
guonaihong
2019-10-05 13:39:24 +08:00
@banxi1988 大,golang 语言特色。刚刚的代码编译的库大约 3.4MB

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/606388

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX