gpt4 book ai didi

go - 如何使用 slice 作为参数从 Go 调用 Rust 函数?

转载 作者:IT王子 更新时间:2023-10-29 00:57:49 25 4
gpt4 key购买 nike

我想通过对 slice 的引用从 Go 调用一些用 Rust 编写的外部函数。

我有以下 Rust 代码:

extern crate libc;

#[no_mangle]
pub extern "C" fn callme(data: &mut [libc::c_double]) -> i32 {
data.len() as i32
}

此函数通过此 C 风格的头文件可供 cgo 编译器使用:

#IFNDEF BOGUSLIB_H
#DEFINE BOGUSLIB_H

extern int callme(double* data);

#ENDIF

我现在可以使用编译为 cdylib 的 Rust crate 从 Go 调用这个函数:

//#cgo CFLAGS: -Ipath/to/libfolder
//#cgo LDFLAGS: -Lpath/to/libfolder -lboguslib
//#include <boguslib.h>
import "C"
import (
"unsafe"
. "fmt"
)

func CallmeExternal() {
data := make([]float64, 1, 1)
data[0] = 1.0
ptr := (*C.double)(unsafe.Pointer(&data[0]))
size := C.callme(ptr)

printf("size %v",size)
}

Go 代码使用不安全指针技巧来访问后备数组,因为 slice 定义如下

type Slice struct {
data *byte
uint32 len
uint32 cap
}

当我执行上面的代码时,传递的引用的长度非常大。我如何访问实际数据,此时返回的是什么?

最佳答案

根据 The Rust FFI Omnibus作为provided by @matthieu-m ,我已经成功重写了代码。函数签名必须接受目标语言可以理解的类型。

Rust 函数签名更改为:

#[no_mangle]
pub extern "C" fn callme(slice: *const libc::c_double, len: libc::size_t) -> libc::c_int {
let data = slice::from_raw_parts(slice, len as usize);
data.len() as i32
}

头文件中声明如下:

// skip include guards
#include <stdio.h>

extern int callme(double* slice, size_t len);

Go 的调用现在也发生了变化

func CallmeExternal() {
data := make([]float64, 2, 2)
data[0] = 1.0
ptr := (*C.double)(unsafe.Pointer(&data[0]))
len := C.size_t(len(data))
size := C.callme(ptr, len)

printf("size %v",size)
}

这将返回 2

关于go - 如何使用 slice 作为参数从 Go 调用 Rust 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47074919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com