为什么我们无法进行良好的比较?ruby-ffi调用golang(so文件)

huangapple go评论92阅读模式
英文:

Why can't we make a good comparison? ruby-ffi call golang(so files)

问题

我正在使用ruby-ffi调用由Golang创建的共享文件。
然而,当我单独运行Golang时,进程可以正常工作,但是当我通过ruby-ffi运行它时,比较就无法正常工作。

以下是一个可能出错的示例。
首先,创建一个go build并加载它。

go build -buildmode=c-shared -o replace.so replace.go
module Sample
  extend FFI::Library
  ffi_lib 'replace.so'

  attach_function :zen_roma_to_han_roma, [:string], :string
end
[5] pry(main)> Sample.zen_roma_to_han_roma("test")
=> "test"

我不知道这个问题的原因,我需要你的帮助。
还有其他什么我应该尝试的吗?

英文:

I'm calling shared files created by Golang from ruby-ffi.
However, when I run Golang alone, the process works, but when I run it via ruby-ffi, the comparison doesn't work.

package main

import (
  "C"
  "fmt"
)

//export zen_roma_to_han_roma
func zen_roma_to_han_roma(s string) string {
  if s=="test" {
    return "10"
  }
  return s
}

func main(){
  fmt.Println(zen_roma_to_han_roma("test"))
}
$ go run replace.go                                                                                                                                                               
10

Here's an example of what can go wrong.
First, create a go build and load it.

go build -buildmode=c-shared -o replace.so replace.go     
module Sample
  extend FFI::Library
  ffi_lib 'replace.so'

  attach_function :zen_roma_to_han_roma, [:string], :string
end
[5] pry(main)> Sample.zen_roma_to_han_roma("test")
=> "test

I don't know the cause of this and I need your help.
Is there anything else I should try?

答案1

得分: 1

我不是Golang程序员,但是这是来自FFI gem文档的一句引用:

> :string 应该被视为 const char *,只要库在访问期间不改变Ruby字符串。如果要从C或Ruby端修改字符串缓冲区,请使用 :pointerFFI::MemoryPointer

因此,你应该将 *C.char 作为参数传递,并返回相同类型的值,而不是 string

package main

import (
  "C"
  "fmt"
)

//export zen_roma_to_han_roma
func zen_roma_to_han_roma(s *C.char) *C.char {
  test_string := C.GoString(s)
  if test_string == "test" {
    return C.CString("10")
  }
  return s
}

func main() {
   fmt.Println(C.GoString(zen_roma_to_han_roma(C.CString("test"))))
}
英文:

I am not a Golang programmer but still here is a quote from the FFI gem documentation

> :string should be considered to be const char * and the Ruby string must not be changed as long as it’s accessed by the library. If the string buffer shall be modified from C or Ruby side, use :pointer and FFI::MemoryPointer instead.

So you should pass *C.char as an argument and return a value of the same type instead of string.

package main

import (
  "C"
  "fmt"
)

//export zen_roma_to_han_roma
func zen_roma_to_han_roma(s *C.char) *C.char {
  test_string := C.GoString(s)
  if test_string == "test" {
    return C.CString("10")
  }
  return s
}

func main() {
   fmt.Println(C.GoString(zen_roma_to_han_roma(C.CString("test"))))
}

huangapple
  • 本文由 发表于 2021年7月1日 18:17:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/68208384.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定