【发布时间】:2018-03-16 23:46:36
【问题描述】:
我目前正在编写一些基本的 cgo 代码。根据cgo documention about Go to C references:
要直接访问结构、联合或枚举类型,请在其前面加上前缀 struct_、union_ 或 enum_,如 C.struct_stat。
我对这句话的理解是,如果我在 C 中有一个名为 Foo 的结构体,我在 Go 中必须使用 C.struct_Foo 类型。
我写了一些 Go 代码,例如:
package main
// #cgo LDFLAGS: -lnavilink -lserialport
// #cgo CFLAGS: -I/usr/local/include
// #include<navilink/navilink.h>
import "C"
import "errors"
func (d *Device) navilinkErrorToGoError() error {
errorC := C.navilink_get_error_description(d.navilinkC)
return errors.New(C.GoString(errorC))
return nil
}
// Device représente une interface
// vers le port série connecté au GPS
type Device struct {
navilinkC *C.struct_NavilinkDevice
}
// Open permettra au développeur d'ouvrir la communication
func (d *Device) Open(path string) error {
res := C.navilink_open_device_from_name(C.CString(path), d.navilinkC)
if res < 0 {
return d.navilinkErrorToGoError()
}
return nil
}
// Close permettra au développeur de fermer la communication
func (d *Device) Close() {
C.navilink_close_device(d.navilinkC)
}
我遇到如下编译错误:
无法将 d.navilinkC(类型 *_Ctype_struct_NavilinkDevice)转换为 类型 _Ctype_struct___1
C结构体的定义如下:
typedef struct {
struct sp_port* serial_port;
struct sp_event_set* event_set;
uint8_t buffer[NAVILINK_MAX_PACKET_SIZE];
NavilinkInformation informations;
int firmware_version;
NavilinkPacket response_packet;
int last_error_code;
} NavilinkDevice;
如果我使用C.DeviceNavilink 而不是C.DeviceNavilink 作为字段的类型,则编译成功。
每个 C 函数都需要一个指向 NavilinkDevice C 结构的指针作为最后一个参数。 C库的代码可以找到here
为什么上面的文档语句意味着你可以不使用任何前缀来引用 C 类型?两者有什么区别?
【问题讨论】:
-
请发送minimal reproducible example。如果
Foo只是一个结构,那么void will_allocate_foo(Foo *foo){声明无效。这例如运行良好:play.golang.org/p/WSARkds3-ZE -
我不确定为什么 C 声明无效?
-
如果
Foo是一个命名结构,那么你必须在类型前面加上struct,就像我的例子一样。 -
我更新了提供的代码。在原始 C 源代码中,我使用了 typedef 而不是命名结构。
标签: c go compilation cgo