记录下go和c互访注意事项

记录下go和c互访注意事项,第1张

概述Go和C互相调用访问时内存注意编译命令实验背景实验1:通过调研go的函数来屏幕输出实现细节结论实验2:go返回非指针类型给c结论实验3:go返回指针结论综上所述编译命令go编译成dll:gobuild-buildmode=c-shared-odll文件名.dllgo文件名.go注意:编译成功后会在

Go和C互相调用访问时内存注意编译命令实验背景实验1:通过调研go的函数来屏幕输出实现细节结论实验2:go返回非指针类型给c结论实验3:go返回指针结论综上所述

编译命令

go编译成dll:

go build -buildmode=c-shared -o dll文件名.dll go文件名.go

注意:编译成功后会在本地目录.生成一个dll和相应的.h头文件,其中描述的是go的数据类型在c中的对应.调用时建议引用.

简化版的加载dll:

gcc -s -w xxx.c xxx.dll -o xxx

-s -w压缩选项,可不要(顺便提一句,go编译的时候加入-ldflags="-s -w"可以减小体积).

实验背景

手头有个项目要完成c的中文处理,需要用到中文字符切片,但是c没有明确给出方法,而且文件编码很头疼.联想到golang不需要在意文件编码这一优势,所以需要互访.

实验1:通过调研go的函数来屏幕输出实现细节

上手dll函数:

package mainimport "fmt"import "C"//export Printffunc Printf(format, str string) {    fmt.Printf(format, str)}func main(){}

要导出的函数前面一行必须一个空格不加一个不少的格式,写上:
//export 函数名
然后函数主体部分,都是正常的.然后必须有个main函数,不会被导出,但是编译器需要它,这是必须的,尤其是"package main"导致了必须存在main()函数
然后运行编译命令,生成:

下面写c语言调用代码:

#include "eee.h"#include <stdio.h>int main() {	char fstr[]="哈哈哈中文输出,数据来源:c文件[%s]\n";	GoString fm = {fstr, sizeof(fstr)};    char *v = malloc(33);    file *fp = fopen("a.txt", "r");    if (!fp) {return;}    fread(v, sizeof(char), 30, fp);    GoString values={v,30};    Printf(fm, values);}

编译运行

结论

golang可以直接访问c的内存,毕竟a.txt的内容是保存在用c语言开辟的空间里.

实验2:go返回非指针类型给c

go:

//export Cutfunc Cut(s string, i int) string{	s1 := string([]rune(s)[i])	print("in go1", s1)	print("int go2", i)	return s1}


输出到关键一部分就不行了…

结论

(勉强挤出)go不要直接返回非指针结果,这回导致不可预料结果.解决方案[理论上]取结构体地址,把地址返回给c

实验3:go返回指针

返回*C.char试试呢?

//export Cutfunc Cut(s string, i int) *C.char{	s1 := string([]rune(s)[i])	print("in go1", s1)	print("int go2", i)	return C.CString(s1)}
    char *vvs = Cut(values, 1);    GoString vv={vvs, strlen(vvs)+1};    Printf(fm, vv);

结论

[反证法]直接返回指针是没问题的,c也可以直接访问.
[题外话]我又加了一句printf("%s\n"),也没问题

综上所述

c->go传参只要按照go提供的数据格式,就基本没问题;
go->c安全的话应该返回指针而不是数据内容.

总结

以上是内存溢出为你收集整理的记录下go和c互访注意事项全部内容,希望文章能够帮你解决记录下go和c互访注意事项所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1221900.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存