【问题标题】:How do I provide access to the library I wrap with cgo?如何提供对我用 cgo 包装的库的访问权限?
【发布时间】:2014-02-09 00:21:35
【问题描述】:

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

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

type Device struct {
    d *C.nfc_device
} 

libnfc 中所有在 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 的访问?

【问题讨论】:

    标签: c go wrapper accessor cgo


    【解决方案1】:

    我一般赞成你的第三个建议,因为这是reflect package handles this issue 的方式。

    您还可以做的是在您的 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 的内部工作。

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多