Обаждане на Rust от Swift

От страна на Rust написах функция, която връща String като указател на байтове (изложен в паметта като 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, се добавя към списъка със зависимости. Заглавката и папките за включване са дефинирани в свойствата на компилацията.

От бърза страна извиквам функцията 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'

Как мога да разреша или заобиколя тази грешка?


person Nicolas Marshall    schedule 20.03.2020    source източник
comment
Имам чувството, че предефинирате типа RustByteSlice в Swift, вместо просто да използвате импортирания тип.   -  person NebulaFox    schedule 21.03.2020


Отговори (1)


След като обработите своя код, вие предефинирате RustByteSlice.

Не ви трябва за да го предефинирате, тъй като автоматично импортира структурата.

Следният бърз код работи.

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
}

person NebulaFox    schedule 21.03.2020
comment
Отлично, благодаря много! И благодаря, че ме насочихте към правилните документи - person Nicolas Marshall; 21.03.2020