我正在尝试为C库(特别是libnfc)编写绑定(bind)。我当前的代码可以在Github上找到。

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

type Device struct {
    d *C.nfc_device
}

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

    这将使从其他模块中访问底层nfc_device变得容易,但也使避开类型安全性变得容易。另外,我不知道cgo是否可以识别来自不同模块的指向外部类型的指针。最后,如果我更改设备类型的结构,则会失去灵活性。
  • 添加访问者func (Device) GetCPtr() unsafe.Pointer
    这解决了上述问题,但引入了新问题:您突然可以访问模块中甚至无法导入unsafe.Pointerunsafe
  • 添加访问者func (Device) GetCPtr() uintptr
    这样就解决了上述问题,因为您必须手动强制转换结果以获取正确的指针。

  • 有什么我想念的方式吗?有没有更好,更惯用的方法来提供对底层nfc_device的访问?

    最佳答案

    我通常赞成您的第三个建议,因为这是 reflect packagehandles this issue的方式。

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

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

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

    此外,您的device类型实现了一个功能
    func (d *device) NfcDevice() *C.nfc_device {
        return d.nfc_device
    }
    

    您可以通过断言NFCDevice来实现在其他包装中使用的代码
    界面
    interface {
        NfcDevice() *C.nfc_device
    }
    

    您可以在其他包装中动态创建。这样程序员必须刻意
    做一些事情来访问device的内部工作原理。

    关于c - 如何提供对使用cgo包装的库的访问权限?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21653547/

    10-14 05:15