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

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

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

问题

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

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

  1. go build -buildmode=c-shared -o replace.so replace.go
  1. module Sample
  2. extend FFI::Library
  3. ffi_lib 'replace.so'
  4. attach_function :zen_roma_to_han_roma, [:string], :string
  5. end
  1. [5] pry(main)> Sample.zen_roma_to_han_roma("test")
  2. => "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.

  1. package main
  2. import (
  3. "C"
  4. "fmt"
  5. )
  6. //export zen_roma_to_han_roma
  7. func zen_roma_to_han_roma(s string) string {
  8. if s=="test" {
  9. return "10"
  10. }
  11. return s
  12. }
  13. func main(){
  14. fmt.Println(zen_roma_to_han_roma("test"))
  15. }
  1. $ go run replace.go
  2. 10

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

  1. go build -buildmode=c-shared -o replace.so replace.go
  1. module Sample
  2. extend FFI::Library
  3. ffi_lib 'replace.so'
  4. attach_function :zen_roma_to_han_roma, [:string], :string
  5. end
  1. [5] pry(main)> Sample.zen_roma_to_han_roma("test")
  2. => "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

  1. package main
  2. import (
  3. "C"
  4. "fmt"
  5. )
  6. //export zen_roma_to_han_roma
  7. func zen_roma_to_han_roma(s *C.char) *C.char {
  8. test_string := C.GoString(s)
  9. if test_string == "test" {
  10. return C.CString("10")
  11. }
  12. return s
  13. }
  14. func main() {
  15. fmt.Println(C.GoString(zen_roma_to_han_roma(C.CString("test"))))
  16. }
英文:

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.

  1. package main
  2. import (
  3. "C"
  4. "fmt"
  5. )
  6. //export zen_roma_to_han_roma
  7. func zen_roma_to_han_roma(s *C.char) *C.char {
  8. test_string := C.GoString(s)
  9. if test_string == "test" {
  10. return C.CString("10")
  11. }
  12. return s
  13. }
  14. func main() {
  15. fmt.Println(C.GoString(zen_roma_to_han_roma(C.CString("test"))))
  16. }

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:

确定