【问题标题】:How do I convert an io.Reader to a std::istream with SWIG & CGO?如何使用 SWIG 和 CGO 将 io.Reader 转换为 std::istream?
【发布时间】:2015-12-31 20:40:13
【问题描述】:

我正在尝试使用 SWIG 为使用 std::istream 读取二进制数据的 C++ API 创建 Go 包装器。我希望能够将io.Reader 传递给这些API,但我不确定如何在它和std::istream 之间创建映射。我知道我需要实现一个 std::streambuf 子类,并且我认为其余部分将涉及导向器和类型映射,但我对 SWIG 不够熟悉,无法找出正确的组合。

有什么想法吗?

【问题讨论】:

  • 您找到解决方案了吗?
  • 不,还没有。对不起!

标签: c++ go swig istream cgo


【解决方案1】:

io.Reader 过于笼统,无法传递给 C 函数——它可能根本不支持真实文件(它只是一个实现 Read(...) 函数的类)

你可以做的(只要你不在 Windows 上)是使用 os.Pipe() 给你一个真正的 FH 对象,但遗憾的是股票 std::*stream 没有任何创建流的方法从打开的文件句柄。

管道钻头看起来像这样:

func wrapReader(r io.Reader) uintptr {
    pr, pw, err := os.Pipe()
    if err != nil {
        panic(err)
    }

    go func () {
        _, _ io.Copy(pw, r)
        _ = pw.Close()
    }()

    return pr
}

如果你在这个答案How to construct a c++ fstream from a POSIX file descriptor? 中结合一些代码,你可能会得到你需要的东西

【讨论】:

  • std::istream 只是像io.Reader 这样的字节流的抽象。只有std::ifstream 实现真正处理文件。
  • 对,对。这是更多的工作,但可能有可能编写一个回调到 go 从 io.Reader 读取的适配器。让 GC 正确,以免读者在你手下被摧毁,这可能是大部分工作的地方。
  • 好吧,由于 Go 不允许将 Go 指针传递给 C 代码,因此通常的解决方案是将对象存储在映射中并来回传递密钥。该对象在从地图中移除之前不会被 GC 处理。我的问题不在于如何制作 std::streambuf,而是如何让 SWIG 在遇到采用 std::istream 的 C++ API 时使用该实现。
猜你喜欢
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多