英文:
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端修改字符串缓冲区,请使用 :pointer
和 FFI::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"))))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论