无法在cgo中访问C变量。

huangapple go评论126阅读模式
英文:

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()
}
  1. 我必须定义_GNU_SOURCE来获取UTMPX_FILE的定义。
  2. 我必须创建path_utmpx变量来解决CGo中的#define问题。
  3. 我必须进行typedef才能使type record C.utmpx编译通过。
  4. 在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 &quot;os&quot;

/*
#define _GNU_SOURCE 1
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;utmpx.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;

char *path_utmpx = UTMPX_FILE;

typedef struct utmpx utmpx;
*/
import &quot;C&quot;

type record C.utmpx

func main() {
	path := C.GoString(C.path_utmpx)
	fd, err := os.Open(path)
	if err != nil {
		panic(&quot;bad&quot;)
	}
	fd.Close()
}
  1. I had to define _GNU_SOURCE to get the UTMPX_FILE definition.
  2. I had to create the path_utmpx variable to get around the #define problems with CGo.
  3. I had to do the typedef to get type record C.utmpx compile.
  4. 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!

huangapple
  • 本文由 发表于 2017年5月18日 07:38:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/44036358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定