Ruby와 Go 간의 포털(FFI 사용)
가능한 FFI 기반 프로토 타입으로 끝났습니다. 해결책은 Ruby 코드가 Go 라이브러리를 로드하고 Ruby 클래스 및 메서드에서 Go 함수를 래핑하도록 하는 것입니다.
루비 쪽
Ruby 쪽은 매우 간단합니다. Go 라이브러리를 로드하고 Ruby 클래스 및 메서드에서 Go 함수를 가져와야 합니다.
require 'ffi'
module Portal
extend FFI::Library
ffi_lib './libexample.so'
class Example < FFI::Struct
# This must be completely in sync with the C struct defined in Go code.
layout :id, :int, :prefix, :pointer
def initialize(prefix, id)
self[:prefix] = FFI::MemoryPointer.from_string(prefix)
self[:id] = id
end
# This feels convoluted, but it hides the fact that our function is loaded
# outside of the "struct mirror" class.
def greet
Portal.greet(self)
end
end
attach_function 'greet', [Example.by_value], :void
end
ex = Portal::Example.new('C', 137)
ex.greet
이동 측
Go 쪽은 좀 더 복잡합니다. C 호환 구조체를 정의하고 Ruby에서 사용하려는 함수를 내보내야 합니다.
멋진 점은 구조체를 수신기로 사용하여 함수를 정의할 수 있다는 것입니다.
package main
/*
struct example {
int ID;
char *Prefix;
};
*/
import "C"
import "fmt"
// This declaration is just an alias to the C struct.
type Example C.struct_example
//export greet
func (e Example) greet() {
fmt.Printf("Hello from %s-%d\n", C.GoString(e.Prefix), e.ID)
}
func main() {}
빌드
빌드도 직관적입니다. 우리는 다음을 수행해야 합니다.
go build -buildmode=c-shared -o libexample.so example.go
ruby portal.rb
결과
코드를 실행하면 다음과 같은 결과가 나타납니다.
Hello from C-137
혜택
이 접근 방식의 주요 이점은 Ruby 코드를 Go로 점진적으로 마이그레이션할 수 있다는 것입니다. 순수한 Go 서비스로 전환할 준비가 될 때까지 부분적으로 교체하여 시작할 수 있습니다.
기존 Ruby 코드를 대체하는 것만 가능한 것은 아닙니다. 이제 RSpec/Minitest 사양을 재사용하여 새로운 Go 코드를 테스트할 수 있습니다. 테스트 없이 완전히 다시 작성하는 대신 기존 코드로 새 코드를 테스트하는 것으로 시작할 수 있습니다.
(가능한) 단점
성능 측면에서 이 접근 방식은 이상적이지 않습니다. 우리는 간접 레이어를 추가하고 있습니다. 이것은 아마도 호출에 약간의 오버헤드를 추가할 것입니다. 이는 트래픽이 많은 서비스에 적용할 경우 측정해야 할 사항입니다.
Reference
이 문제에 관하여(Ruby와 Go 간의 포털(FFI 사용)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dcc/a-portal-between-ruby-and-go-using-ffi-48gn텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)