Как вернуть строку из функции в Ruby с помощью CGO - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть функция в Go:

func login(user *C.char) *C.char {
    cstr := C.CString("Hello World")
    defer C.free(unsafe.Pointer(cstr))
    return cstr 
}

Мой код рубина, как показано ниже

module GoLib
  extend FFI::Library
  ffi_lib './golib.so'

  attach_function :login, [:string], :string
end

GoLib.login("User1") #=> "p\x9A\xA0\xDB\x16V"

, он не возвращается в виде строки рубина.Как это исправить?

1 Ответ

0 голосов
/ 04 декабря 2018

Как указано в комментариях, cstr становится бесплатным после передачи управления Ruby.Вот обходной путь, где вы явно управляете указателем в Ruby.

package main

// #include <stdlib.h>
import "C"
import "unsafe"

//export login
func login(user *C.char) *C.char {
    return C.CString("Hello from Go")
}

//export logout
func logout(c *C.char) {
    C.free(unsafe.Pointer(c))
}

func main() {}

В Ruby:

require 'ffi'

module GoLib
  extend FFI::Library
  ffi_lib './so.so'

  attach_function :login, [:string], :strptr
  attach_function :logout, [:pointer], :void
end

s, p = GoLib.login("User1")
puts s
p = FFI::AutoPointer.new(p, GoLib.method(:logout))

Обратите внимание на использование strptr, как продемонстрировано здесь

...