Ich versuche die Möglichkeit zu schaffen, eine Rust-Funktion von go aufzurufen und dann ruft diese Rust-Funktion die Funktion to go zurück. Ich verwende CGO als FFI-Schnittstelle zwischen Go und Rust. Hier ist mein Go-Code (src/main.go):
package main import ( "c" "fmt" "unsafe" ) /* #cgo cflags: -i./../lib #cgo ldflags: -l./../bin -lgo_move -wl,-rpath=./bin #include "move.h" */ //export cosmoscallbackwrapper func cosmoscallbackwrapper(data *c.uchar, datalen c.int) { // convert data to go slice godata := c.gobytes(unsafe.pointer(data), datalen) // call the actual callback function cosmoscallback(godata) } // setcosmoscallback sets the callback function to be called by the move vm. func setcosmoscallback(callback func([]byte)) { cosmoscallback = callback c.set_cosmos_callback((c.cosmos_callback)(unsafe.pointer(c.cosmoscallbackwrapper))) } var cosmoscallback func([]byte) func main() { // create a new move interpreter // set the callback function setcosmoscallback(func(data []byte) { fmt.println("received data from move vm:", data) // handle data and call cosmos sdk functions as needed }) }
Das ist mein Rust-Code (src/lib.rs)
use std::os::raw::{c_char, c_int}; use std::ffi::cstring; use std::sync::mutex; #[macro_use] extern crate lazy_static; pub fn main() { } pub type cosmoscallback = extern "c" fn(*const c_char, c_int); lazy_static! { static ref callback: mutex<option<cosmoscallback>> = mutex::new(none); } #[no_mangle] pub extern "c" fn set_cosmos_callback(callback: cosmoscallback) { let mut cb = callback.lock().unwrap(); *cb = some(callback); } #[no_mangle] pub extern "c" fn cosmoscallbackwrapper(data: *const c_char, data_len: c_int) { let cb = callback.lock().unwrap(); if let some(callback) = &*cb { callback(data, data_len); } }
Das ist meine Datei „cargo.toml“:
[package] name = "go-move" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] libc = "0.2" lazy_static = "1.4.0" [workspace] members = [ ".",]
Dies ist lib/move.h (die Header-Datei der gemeinsam genutzten Bibliothek):
#ifndef move_vm_lib_h #define move_vm_lib_h #include <stdint.h> //typedef void (*cosmos_callback)(const unsigned char *data, int data_len); //void set_cosmos_callback(cosmos_callback callback); typedef void (*cosmos_callback)(const uint8_t* data, int32_t data_len); void set_cosmos_callback(cosmos_callback callback); #endif
Das ist mein Makefile:
shell := /bin/bash .phony: build os = $(shell uname) clean: rm -rf bin rm -rf target build: @echo the os is $(os) mkdir bin cargo build --release ifeq ($(os),linux) cp target/release/libgo_move.so bin/ else cp target/release/libgo_move.dylib bin/ endif cp -a lib/. bin/ go build --ldflags="-l./bin -lgo_move" -o bin/main src/main.go run: export ld_library_path=./bin && ./main
Die Dateistruktur ist wie folgt:
src main.go main.rs bin libgo_move.so (after cargo build) lib move.h cargo.toml makefile
Nach dem Ausführen make clean build
erhalte ich folgende Ausgabe:
cp target/release/libgo_move.so bin/ cp -a lib/. bin/ go build -o bin/main src/main.go # command-line-arguments src/main.go:27:59: could not determine kind of name for C.cosmosCallbackWrapper src/main.go:27:25: could not determine kind of name for C.cosmos_callback src/main.go:27:2: could not determine kind of name for C.set_cosmos_callback
Aus irgendeinem Grund kann die FFI-Funktion nicht gefunden werden.
Das ist ein dummer Fehler:
/* #cgo CFLAGS: -I./../lib #cgo LDFLAGS: -L./../bin -lgo_move -Wl,-rpath=./bin #include "move.h" */
Muss vor dem Import erfolgen. Das ist alles.
Das obige ist der detaillierte Inhalt vonCallback-Funktionen von Rust to Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!