我编写了以下肮脏的 hack 来解决明显无法从 C 访问 Go 结构的问题。虽然不能保证这种 hack 有效,但它适用于 Go 和 C 就如何布局结构达成一致的情况,这恰好是我感兴趣的所有案例的案例。
对于我想访问的每个 Go 结构
type JewelTarget struct {
SensRes [2]byte
Id [4]byte
Baud int
}
我创建了一个相应的 C 结构,它具有相同宽度的字段并希望具有相同的布局:
typedef ptrdiff_t GoInt;
struct JewelTarget {
uint8_t SensRes[2];
uint8_t Id[4];
GoInt Baud;
};
然后我编写使用这些 C 结构的 C 函数:
extern void
marshallJewelTarget(nfc_target *nt, const struct JewelTarget *jt)
{
nfc_jewel_info *ji = &nt->nti.nji;
memcpy(ji->btSensRes, jt->SensRes, sizeof(jt->SensRes));
memcpy(ji->btId, jt->Id, sizeof(jt->Id));
nt->nm.nbr = jt->Baud;
nt->nm.nmt = NMT_JEWEL;
}
并像参数具有相应的 Go 类型一样调用它们:
func (d *JewelTarget) Marshall() uintptr {
nt := mallocTarget()
jt := (*C.struct_JewelTarget)(unsafe.Pointer(d))
C.marshallJewelTarget(nt, jt)
return uintptr(unsafe.Pointer(nt))
}
所有示例均取自我的nfc 绑定。