1

我正在尝试为 C 库编写绑定,特别是libnfc。我当前的代码在Github上可用。

libnfc 中的核心结构之一是设备。它由 Go 类型表示Device

type Device struct {
    d *C.nfc_device
} 

libnfc 中所有对 a 进行操作的函数Device都是它的方法。现在,还有其他 C 库(例如 libfreefare),其 API 在nfc_devicees 上运行。为了模块化,我想将我包装的每个库的代码放入它自己的模块中。这导致了问题,即我无法从其他模块中访问私有结构成员。我想到了以下解决方案:

  • 成为d公共成员Device

    这将使nfc_device从其他模块中访问底层变得容易,但它也使得回避类型安全也变得容易。此外,如果 cgo 来自不同的模块,我不知道是否可以识别指向外部类型的指针。最后,如果我更改 Device 类型的结构,我将失去灵活性。

  • 添加访问器func (Device) GetCPtr() unsafe.Pointer

    这解决了上述问题,但引入了一个新问题,即您突然可以访问一个unsafe.Pointer甚至可能无法导入的模块中的一个unsafe

  • 添加访问器func (Device) GetCPtr() uintptr

    这解决了上述问题,因为您必须手动转换结果才能获得正确的指针。

有什么我错过的方法吗?是否有更好、更惯用的方式来提供对底层的访问nfc_device

4

1 回答 1

1

我一般赞成你的第三个建议,因为这是reflect包处理这个问题的方式。

您还可以做的是仅在您的 libnfc 包装器中公开一个接口,例如

type NFCDevice interface {
    Read() ([]byte, error)
    Write() ([]byte, error)
    // ...
}

现在您有了一个安全的公共 API。

此外,您的device类型实现了一个功能

func (d *device) NfcDevice() *C.nfc_device {
    return d.nfc_device
}

您可以通过断言您NFCDevice实现接口来在其他包装器中使用它

interface {
    NfcDevice() *C.nfc_device
}

您可以在其他包装器中即时创建。这样,程序员必须故意做一些事情来访问你的device.

于 2014-02-09T01:25:38.147 回答