• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    在Golang中使用C语言代码实例

    cgo 使得在 Golang 中可以使用 C 代码。

    Hello World

    为了有一个较为直观的了解,我们来看一个简单的例子,创建文件 main.go:

    复制代码 代码如下:

    package main
     
    /*
    #include stdio.h>
     
    void sayHi() {
        printf("Hi");
    }
    */
    import "C"
     
    func main() {
        C.sayHi()
    }

    执行程序:
    复制代码 代码如下:

    go run main.go

    程序执行并输出 hi(更多的范例可以见 $GOROOT/misc/cgo)。

    Windows 下的准备工作

    如果想要在 Windows 上使用 cgo,那么需要安装 gcc 编译器,这里我使用 mingw-w64。

    设置编译和链接标志

    我们使用 import “C” 导入的是一个伪包(pseudo-package),我们通过其来使用 C 代码。在 import “C” 之前,紧跟着 import “C” 的注释可以包括:

    1.编译器和链接器标志
    2.C 代码

    我们可以通过 #cgo 指令来设置编译器和链接器标志,例如:

    复制代码 代码如下:

    // #cgo CFLAGS: -DPNG_DEBUG=1
    // #cgo amd64 386 CFLAGS: -DX86=1
    // #cgo LDFLAGS: -lpng
    // #include png.h>
    import "C"

    附带提及一点的是,这些指令中可以包含构建约束(build constraint),详细内容见:http://golang.org/pkg/go/build/#hdr-Build_Constraints。

    常用的 #cgo 指令有:

    1.CPPFLAGS、CFLAGS 指令被用于编译当前包中的 C 文件(任何的 .c、.s、.S 文件)
    2.CPPFLAGS、CXXFLAGS 指令被用于编译当前包中的 C++ 文件(任何的 .cpp、.cc、.cxx 文件)
    3.LDFLAGS 指令用于指定链接器标志
    4.pkg-config 指令用于通过 pkg-config 工具获取编译器和链接器标志(例如:#cgo pkg-config: png cairo)

    Golang 引用 C

    结构体上需要注意的点:

    1.C 结构体的域名称如果为 Golang 的关键字时,访问时需要在域名称前面加上 _。比如说,C 中有一个结构体变量 x,此变量对应的结构体中有一个域 type,那么在 Golang 中需要通过 x._type 来访问 type 域
    2.结构体的位域、非对齐数据等无法在 Golang 中表示时会被忽略
    3.Golang 结构体中不能使用 C 类型的域

    标准的 C 数值类型对应:

    1.C.char
    2.C.schar(signed char)
    3.C.uchar(unsigned char)
    4.C.short
    5.C.ushort(unsigned short)
    6.C.int
    7.C.uint(unsigned int)
    8.C.long
    9.C.ulong(unsigned long)
    10.C.longlong(long long)
    11.C.ulonglong(unsigned long long)
    12.C.float
    13.C.double

    任何的 C 函数(包括 void 函数)都可以返回一个返回值和 C 的 errno 变量(作为错误):

    复制代码 代码如下:

    n, err := C.sqrt(-1)
    _, err := C.voidFunc()

    直接调用 C 函数指针目前还无法支持。

    有一些特殊的函数可以用于 C 类型和 Golang 类型之间转换(通过数据拷贝的方式),伪定义如下:

    复制代码 代码如下:

    // Golang 的字符串转为 C 字符串
    // C 的字符串是使用 malloc 分配的,因此,此函数的调用者
    // 需要调用 C.free 来释放内存
    func C.CString(string) *C.char
     
    // 转换 C 字符串到 Golang 字符串
    func C.GoString(*C.char) string
     
    // 转换一定长度的 C 字符串到 Golang 字符串
    func C.GoStringN(*C.char, C.int) string
     
    // 转换一块 C 内存区域到 Golang 的字节数组中去
    func C.GoBytes(unsafe.Pointer, C.int) []byte

    其他需要注意的点:

    1.C 语言中的 void* 对应 unsafe.Pointer
    2.C 语言中的结构、联合、枚举类型(而非变量),在 Golang 中需要加上 struct_、union_、enum_ 前缀访问。由于 Golang 中没有联合这种数据类型,因此 C 的联合在 Golang 中被表示为字节数组
    3.和 C 语言等价的那些类型是不可以导出的

    您可能感兴趣的文章:
    • C语言和go语言之间的交互操作方法
    • Go语言中嵌入C语言的方法
    • Go语言中CGO的使用实践
    上一篇:GO语言求100以内的素数
    下一篇:Golang极简入门教程(一):基本概念
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    在Golang中使用C语言代码实例 在,Golang,中,使用,语言,代码,