目錄
正確答案
首頁 後端開發 Golang 從 Rust 到 Go 的回呼函數

從 Rust 到 Go 的回呼函數

Feb 05, 2024 pm 11:03 PM
typedef

从 Rust 到 Go 的回调函数

問題內容

我正在嘗試建立從 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

c語言中typedef struct的用法 c語言中typedef struct的用法 May 09, 2024 am 10:15 AM

typedef struct 在 C 語言中用於建立結構體類型別名,簡化結構體使用。它透過指定結構體別名將一個新的資料類型作為現有結構體的別名。優點包括增強可讀性、程式碼重複使用和類型檢查。注意:在使用別名前必須定義結構體,別名在程式中必須唯一且僅在其宣告的作用域內有效。

理解 C++ 函數指標的記憶體管理:避免指標陷阱 理解 C++ 函數指標的記憶體管理:避免指標陷阱 Apr 29, 2024 pm 09:03 PM

在C++中使用函數指標時,必須謹慎考慮記憶體管理以避免陷阱。這些陷阱包括懸浮指標(指向超出其範圍的函數)和野指標(從未初始化或設定為nullptr的函數指標)。為了避免這些陷阱,請遵循以下最佳實踐:始終初始化函數指針,謹慎管理內存,並使用智慧指針。這樣,您就可以安全地使用函數指針,並避免陷入指針陷阱。

typedef的用法是什麼 typedef的用法是什麼 Sep 04, 2023 pm 01:20 PM

typedef的用法是為已經存在的資料類型建立新的別名。使用typedef可以增加程式碼的可讀性和可維護性,特別是在處理複雜的資料類型時。對於簡單的資料類型,如整數、浮點數或字符,使用別名的好處並不明顯。然而,對於指標、結構體、陣列和函數等複雜的資料類型,使用別名的優勢就顯而易見了。 typedef不能用於變數或函數定義之前,通常在程式檔案的頂部或結構體定義之後會建立。

Linux核心定時器與延遲工作驅動開發詳解 Linux核心定時器與延遲工作驅動開發詳解 Feb 13, 2024 am 11:57 AM

Linux核心定時器與延遲工作是兩種常用的實現定時任務和延遲執行任務的機制,它們可以讓驅動程式在適當的時間點執行特定的函數,以適應硬體設備的需求和特性。但是,如何正確地使用Linux內核定時器與延遲工作呢?本文將從理論與實務兩方面,介紹Linux核心定時器與延遲工作驅動發展的基本知識與技巧,以及一些常見的問題與解決方法。內核定時器軟體上的定時器最終要依靠硬體時鐘來實現,簡單的說,內核會在時鐘中斷發生後檢測各個註冊到內核的定時器是否到期,如果到期,就回調相應的註冊函數,將其作為中斷底半部來執行。實

c語言簡單煙火程式碼怎麼寫 c語言簡單煙火程式碼怎麼寫 Apr 13, 2024 pm 09:18 PM

要編寫一個簡單的 C 語言煙火程式碼,需要遵循以下步驟:包含頭檔和函式庫。定義常數和巨集。建立粒子資料結構。聲明全域變數。在 main() 函數中初始化煙火粒子。在遊戲循環中更新粒子的位置和速度,並繪製它們。檢查和銷毀已達到壽命的粒子。

c++中typedef struct和struct的差別 c++中typedef struct和struct的差別 May 01, 2024 am 11:36 AM

typedef struct和struct的差別:typedef struct建立結構體類型的別名,而struct定義新的結構體類型。 typedef struct建立的別名在宣告之後即可使用,而struct定義的結構體在定義之後才可使用。 typedef struct和struct都不會建立額外的儲存空間。

用 C++ 函數指標改造程式碼:提升效率和可重複使用性 用 C++ 函數指標改造程式碼:提升效率和可重複使用性 Apr 29, 2024 pm 06:45 PM

函數指標技術可提升程式碼效率和可重複使用性,具體表現為:提升效率:使用函數指標可減少重複程式碼,優化呼叫過程。提高可重複使用性:函數指標允許使用通用函數處理不同數據,提高程式的可重複使用性。

從 Rust 到 Go 的回呼函數 從 Rust 到 Go 的回呼函數 Feb 05, 2024 pm 11:03 PM

我正在嘗試創建從go調用rust函數的可能性,然後所述rust函數將函數回調到go。我使用cgo作為go和rust之間的ffi介面。以下是我的go程式碼(src/main.go):packagemainimport("c""fmt""unsafe")/*#cgocflags:-i./../lib#cgoldflags:-l./../bin -lgo_move-wl,-rpath=./bin#include"m

See all articles