LoginSignup
1
0

More than 5 years have passed since last update.

Ruby から FFI で Go にバイト列のポインタを渡す

Posted at

Ruby を書いていると、バイナリ処理を Go で書いて FFI 呼び出すことでいい感じにしたくなることがあります。

バイナリの受け渡しをする際は、String を使うと NULL 文字で終端されてしまう 1 ため、ポインタで渡してあげる必要があります。

C での書き方は ffi/ffi の wiki に載っていますが、Go での書き方は調べてもあまり出てこないので、ここに書いておきます。

main.go
package main

import (
    "C"
    "bytes"
    "unsafe"
)

//export hoge
func hoge(pointer unsafe.Pointer, size C.int) *C.char {
    // ポインタからバイト列を取り出す
    var data []byte = C.GoBytes(pointer, size)

    // バイト列を使って何か処理する
    var result string = do_something(data)

    // Go の string を C の string に変換して返す
    return C.CString(result)
}

func do_something(data []byte) string {
    return "xxx"
}

func main() {
}
hoge.rb
require 'ffi'

module Hoge
  extend FFI::Library

  # 上記の Go を shared library にコンパイルしたファイル
  ffi_lib 'hoge.so'

  attach_function :hoge, [:pointer, :uint], :string

  class << self
    # ポインタを渡す必要があるので private にしてインターフェイスを call_hoge に統一する
    private :hoge

    # 文字列をポインタに変換してから hoge を呼ぶ
    def call_hoge(string)
      mem_buf = FFI::MemoryPointer.from_string(string)
      hoge(mem_buf, data.bytesize)
    end
  end
end

  1. Binary data · ffi/ffi Wiki https://github.com/ffi/ffi/wiki/Binary-data 

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0