
我正在尝试创建从 go 调用 rust 函数的可能性,然后所述 rust 函数将函数回调到 go。我使用 cgo 作为 go 和 rust 之间的 ffi 接口。 以下是我的 go 代码(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
})
}这是我的 rust 代码 (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);
}
}这是我的 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 = [ ".",]
这是 lib/move.h(共享库的头文件):
#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
这是我的 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文件结构如下:
src
main.go
main.rs
bin
libgo_move.so (after cargo build)
lib
move.h
cargo.toml
makefile运行 make clean build 后,我得到以下输出:
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
由于某种原因,它找不到 ffi 函数。
这是一个愚蠢的错误:
/* #cgo CFLAGS: -I./../lib #cgo LDFLAGS: -L./../bin -lgo_move -Wl,-rpath=./bin #include "move.h" */
必须在导入之前进行。仅此而已。
以上就是从 Rust 到 Go 的回调函数的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号