英文:
Cannot access c variables in cgo
问题
我正在尝试在cgo中访问一个C结构体,但是遇到了这个错误:
>无法确定C.utmpx的名称类型
utmpx是一个C结构体。
以下是Go代码:
/*
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
#include <fcntl.h>
#include <unistd.h>
*/
import "C"
type record C.utmpx
fd, err := os.Open(C._PATH_UTMPX) // 这个可以工作
fd, err := os.Open(C.UTMPX_FILE) // 错误
在utmpx.h文件中,有以下定义:
#define _PATH_UTMPX "/var/run/utmpx"
#define UTMPX_FILE _PATH_UTMPX
我可以使用_PATH_UTMPX,但是使用UTMPX_FILE时会得到相同的警告,为什么?
似乎我无法访问在.h文件中声明的这些变量。我该怎么做?
英文:
I'm trying to access a c struct in cgo, but go this
>could not determine kind of name for C.utmpx
utmpx is a c struct
here is the go code:
/*
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
#include <fcntl.h>
#include <unistd.h>
*/
import "C"
type record C.utmpx
fd, err := os.Open(C._PATH_UTMPX) // this works
fd, err := os.Open(C.UTMPX_FILE) // error
In the utmpx.h file , there is
#define _PATH_UTMPX "/var/run/utmpx"
#define UTMPX_FILE _PATH_UTMPX
I can use _PATH_UTMPX but get the same warn when using UTMPX_FILE, why?
It seems that I cannot access these variables declared in .h file
How can i do this ?
platform: macOS sirria,go 1.8
答案1
得分: 0
#define在CGo中存在问题。我可以在Linux amd64上使用Go 1.8.1解决这个问题,方法如下:
package main
import "os"
/*
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
#include <fcntl.h>
#include <unistd.h>
char *path_utmpx = UTMPX_FILE;
typedef struct utmpx utmpx;
*/
import "C"
type record C.utmpx
func main() {
path := C.GoString(C.path_utmpx)
fd, err := os.Open(path)
if err != nil {
panic("bad")
}
fd.Close()
}
- 我必须定义_GNU_SOURCE来获取UTMPX_FILE的定义。
- 我必须创建path_utmpx变量来解决CGo中的#define问题。
- 我必须进行typedef才能使
type record C.utmpx
编译通过。 - 在Go中,不能直接使用C字符串。你必须将它们转换为Go字符串。同样,如果你想使用Go字符串调用C函数,你必须将它们转换为C字符串(并释放在堆上分配的空间)。
一些建议:
祝你好运!
英文:
#define's are problematic with CGo. I could get it to work with Go 1.8.1 on Linux amd64 like this:
package main
import "os"
/*
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
#include <fcntl.h>
#include <unistd.h>
char *path_utmpx = UTMPX_FILE;
typedef struct utmpx utmpx;
*/
import "C"
type record C.utmpx
func main() {
path := C.GoString(C.path_utmpx)
fd, err := os.Open(path)
if err != nil {
panic("bad")
}
fd.Close()
}
- I had to define _GNU_SOURCE to get the UTMPX_FILE definition.
- I had to create the path_utmpx variable to get around the #define problems with CGo.
- I had to do the typedef to get
type record C.utmpx
compile. - With Go, you can't use C strings directly. You must convert them to Go strings. Similarly, if you want to call C functions with Go strings, you must convert them to C strings (and free the space allocated in the heap).
A few pointers:
Good luck!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论