dongzhang6544 2019-01-05 03:22
浏览 417
已采纳

在Golang包中编译CGO文件

I am trying to use CGO to bundle C files with a Golang package. Following instructions here:

https://karthikkaranth.me/blog/calling-c-code-from-go/

http://akrennmair.github.io/golang-cgo-slides/#1

https://golang.org/cmd/cgo/

I am getting this error:

# main 
src/main/main.go:16:8: could not determine kind of name for C.free 
src/main/main.go:23:10: could not determine kind of name for C.greet

here is the structure:

enter image description here

main.go just looks like:

package main

// #cgo CFLAGS: -g -Wall
// #include <stdlib.h>
// #include "genericc/greeter.h"

import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    name := C.CString("Gopher")
    defer C.free(unsafe.Pointer(name))

    year := C.int(2018)

    ptr := C.malloc(C.sizeof_char * 1024)
    defer C.free(unsafe.Pointer(ptr))

    size := C.greet(name, year, (*C.char)(ptr))

    b := C.GoBytes(ptr, size)
    fmt.Println(string(b))
}

and I run test.sh to build it:

#!/usr/bin/env bash

dir="$(cd `dirname "$0"` && pwd)"
export GOPATH="$dir"

cd "$dir"

export CGOFILES=main
go install main

but when I run the bash script I get that error.

  • 写回答

2条回答 默认 最新

  • douzhuo2002 2019-01-05 03:28
    关注

    I follow the instructions:

    Command cgo

    If the import of "C" is immediately preceded by a comment, that comment, called the preamble, is used as a header when compiling the C parts of the package. For example:

    // #include <stdio.h>
    // #include <errno.h>
    import "C"
    

    or

    /*
    #include <stdio.h>
    #include <errno.h>
    */
    import "C"
    

    For example,

    gocbuf.go:

    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    /*
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int printData(unsigned char *data) {
        return printf("cData: %lu \"%s\"
    ", (long unsigned int)strlen(data), data);
    }
    */
    import "C"
    
    func main() {
        // Allocate C data buffer.
        width, height := 8, 2
        lenData := width * height
        // add string terminating null byte
        cData := (*C.uchar)(C.calloc(C.size_t(lenData+1), C.sizeof_uchar))
    
        // When no longer in use, free C allocations.
        defer C.free(unsafe.Pointer(cData))
    
        // Go slice reference to C data buffer,
        // minus string terminating null byte
        gData := (*[1 << 30]byte)(unsafe.Pointer(cData))[:lenData:lenData]
    
        // Write and read cData via gData.
        for i := range gData {
            gData[i] = '.'
        }
        copy(gData[0:], "Data")
        gData[len(gData)-1] = 'X'
        fmt.Printf("gData: %d %q
    ", len(gData), gData)
        C.printData(cData)
    }
    

    Output:

    $ go run gocbuf.go
    gData: 16 "Data...........X"
    cData: 16 "Data...........X"
    $ 
    

    Your code organization makes no sense to me.

    You should have package greeter, which wraps C functions via cgo. For example,

    src
    └── greeter
        ├── greeter.c
        ├── greeter.go
        └── greeter.h
    

    with skeleton files

    greeter.go:

    package greeter
    
    /*
    #include "greeter.h"
    */
    import "C"
    

    greeter.c:

    #include "greeter.h"
    

    greeter.h

    /* C header file */
    

    To install the greeter package, simply use go install.

    Don't use relative paths. Don't use bash scripts.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#stm32#的问题:寻找一块开发版,作为智能化割草机的控制模块和树莓派主板相连,要求:最低可控制 3 个电机(两个驱动电机,1 个割草电机),其次可以与树莓派主板相连电机照片如下:
  • ¥15 Mac(标签-IDE|关键词-File) idea
  • ¥15 潜在扩散模型的Unet特征提取
  • ¥15 iscsi服务无法访问,如何解决?
  • ¥15 感应式传感器制作的感应式讯响器
  • ¥15 如何使用SC92F8003固件库解析私有协议数据?
  • ¥15 如何在音频中嵌入字符串(水印)信息进行传递
  • ¥30 plc怎么以设计说明书申请软著
  • ¥15 硬盘识别不了,需要初始化,可我的数据怎么办
  • ¥15 lvm2被mask了,怎么unmask都没用(标签-ubuntu|关键词-apt)