c语言获取游戏包名内存读写,在go中调用c语言

作者:2013-08-08

今天上班的时候突然想到一个问题:c语言中的char*该怎么转换成go中的string呢?在go语言交流群中问了一下,得到了一个答案是使用cgo。之前只听过有cgo这么个东西,但是没有真正使用过。今天突然想到了这个问题,就抽出时间学习下cgo,接下来就有了这篇文章。

一、介绍

go有强烈的c背景,除了语法具有继承性外,其设计者以及设计目标都和c有着很大的关系。在go和c语言相互操作方面,go提供了强大的支持。尤其是在go中使用c,甚至可以在go源文件中编写c代码,这是其他语言所无法达到的。

在如下一些场景中,可能涉及到go与c的相互操作:

提升局部代码性能时,用c替代一些go代码。c对于go而言,就像汇编对于c。

觉得go的gc(垃圾回收)性能不足,自己动手管理内存。

实现一些库的go wrapper。比如Oracle提供了c版本的OCI,但是Oracle并未提供go版本驱动以及连接DB的协议细节。因此只能通过包装C版本的OCI以提供go开发者使用。

go导出函数供c开发者使用。

maybe more……

二、go中调用c代码

go中调用c代码会使用到cgo,cgo让go可以非常简单的融合c代码。在import “C”上面添加特殊注释来包含c相关代码,特别注意import “C”和注释的c代码之间一定不能有空行,否则会报错。下面给出了一个小例子:

packagemain/*

#include

#include

void output(char *str) {

printf("%s\n", str);

}

*/import"C"//此处和上面的C代码一定不能有空行 否则会报错import"unsafe"funcmain(){str:="hello cgo"//change to char*cstr:=C.CString(str)C.output(cstr)C.free(unsafe.Pointer(cstr))}

这个例子中,与正常的go代码相比,有几个不同的位置:

注释部分出现了c代码

import了一个”C”的包

在go的main函数中调用了注释中的c函数output

其实这个例子没错,这是go源码中调用c代码的步骤,由此可知在go源码中能直接编写c代码。总结起来go中调用c代码的步骤如下:

go源码文件中的c代码需要用注释起来,就像上面例子中的include头文件和output函数

必须使用import “C”,且这句话和上面注释的c代码之间不能有空行。这里的”C”其实不是包名,而是一种类似名字空间的概念,或可以理解为伪包,c语言的所有语法元素都在该伪包下

访问c语法元素时,都要在其前面加上伪包前缀,比如C.output、C.free等等

说了半天,那么上面的代码该如何编译呢?其实与”正常”go源文件没什么区别,依旧可以直接通过go build或go run来编译和执行。但实际编译过程中,go调用了名为cgo的工具,cgo会识别和读取go源文件中的c元素,并将其提取后交给c编译器编译,最后与go源码编译后的目标文件链接成一个可执行程序。这样我们就不难理解为何go源文件中的c代码要用注释包裹了,这些特殊的语法都是可以被cgo识别并使用的。

PS 1:该开始编译这个程序时,由于gcc版本太低,程序能正常编译通过,但是没有任何输出,找了很久,才发现gcc版本要在4.6之上。

PS 2:最好不用在Sublime Text2提供的命令行下编译,同样也得不到输出。直接在终端才编译才得到了正确输出。

作者:hahaya

出处:http://hahaya.github.com/c-and-go

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值