从 Swift 调用 Rust

标签 c swift rust ffi

在 Rust 方面,我编写了一个函数,该函数返回一个字符串作为字节指针(在内存中作为 C 结构布局):

#[repr(C)]
pub struct RustByteSlice {
    pub bytes: *const u8,
    pub len: size_t,
}

#[no_mangle]
pub extern "C" fn get_string_from_rust() -> RustByteSlice {
    let s = "This is a string from Rust.";
    RustByteSlice {
        bytes: s.as_ptr(),
        len: s.len() as size_t,
    }
}

使用 cbindgen 为它生成头文件时,它给了我以下输出:
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
  const uint8_t *bytes;
  size_t len;
} RustByteSlice;

RustByteSlice get_string_from_rust(void);

char *hello(const char *to);

void hello_release(char *s);

void utf8_bytes_to_rust(const uint8_t *bytes, size_t len);

在我的Xcode项目中,这个头文件作为桥接头文件,将rust代码编译出来的共享库加入到依赖列表中。标题和包含文件夹在构建属性中定义。

在 swift 方面,我通过以下方式调用 rust 函数:
struct RustByteSlice {
    var bytes: UnsafePointer<UInt8>
    var len: Int

    func asUnsafeBufferPointer() -> UnsafeBufferPointer<UInt8> {
        return UnsafeBufferPointer(start: bytes, count: len)
    }
    func asString(encoding: String.Encoding = String.Encoding.utf8) -> String? {
        return String(bytes: asUnsafeBufferPointer(), encoding: encoding)
    }
}

func strPtrRet() {
    let rustString: RustByteSlice = get_string_from_rust()

    if let stringFromRust = rustString.asString() {
        print("got a string from Rust: (stringFromRust)")
    } else {
        print("Could not parse Rust string as UTF-8")
    }
}

上线let rustString: RustByteSlice = get_string_from_rust() ,我收到以下错误:
Cannot convert value of type '__ObjC.RustByteSlice' to specified type 'ed25_ios_app.RustByteSlice'

如何解决或解决此错误?

最佳答案

在完成您的代码后,您正在重新定义 RustByteSlice .

来自 Using Imported C Structs and Unions in Swift ,您不需要重新定义它,因为它会自动导入结构。

下面的快速代码有效。

func strPtrRet() -> String? {
    let rustString: RustByteSlice = get_string_from_rust()
    let buffer = UnsafeBufferPointer(start: rustString.bytes, count: rustString.len)
    let string = String(bytes: buffer, encoding: String.Encoding.utf8)

    if let stringFromRust = string {
        print("got a string from Rust: (stringFromRust)")
    } else {
        print("Could not parse Rust string as UTF-8")
    }

    return string
}

关于从 Swift 调用 Rust,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60782402/

相关文章:

c - 如何使用 TUN/TAP 接口(interface)在两个进程之间发送数据包?

c - 迭代 ldap 搜索结果集

objective-c - 将 NSDate 转换为 NSString

rust - 为什么 Rust RwLock 在 fork 时表现异常?

c - 随 secret 码生成器相同的字符串

c - 单链表中的 InsertAfter 函数 (C)

ios - UIPickerView 中 UIVIew 的背景颜色设置不正确

ios - 如何使用 NSExtensionPrincipalClass 显示 Storyboard UI 进行共享扩展

rust - 我可以将变量赋值与 if 结合使用吗?

types - 是否可以对 Rust 中的泛型进行编译时类型检查?