Проблема преобразования тегового объединения C в перечисление Rust из-за разметки памяти - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь взаимодействовать с API событий C, структурированным так:

struct EventA {
    int type;
    int data1;
    int data2;
};

struct EventB {
    int type;
    int data1;
};

union Event {
    int type;
    EventA eventA;
    EventB eventB;
};

//grabs the next event from the queue.
void pollEvent(Event *event); 

В C API поле type используется, чтобы определить, какой тип события произошел.По сути, это теговое объединение или перечисления в Rust.Я знаю, что Rust позволяет вам выбрать базовый тег перечисления с помощью #[repr(type)], однако я считаю, что Rust не гарантирует, что тег является первым полем перечисления.(Или это всегда последнее поле?) Это делает его довольно грубым при преобразовании API в Rust, потому что мне понадобится некоторый тип структуры-посредника для опроса, затем совпадения с его типом, преобразования его в перечисление, тогда пользователь будет соответствоватьENUM.

Если бы я знал, что тег был первым полем перечисления, я знаю, что перечисление и объединение имеют одно и то же представление памяти, и я мог бы просто передать его как указатель.

Что я хотел бы сделать:

use::std::os::raw::c_int;

#[repr(C)]
#[derive(Copy, Clone)]
pub struct EventA {
    pub data1: c_int,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct EventB {
    pub data1: c_int,
    pub data2: c_int,
}

#[repr(i32)] //I'm assuming c_int is 32 bit.
#[derive(Copy, Clone)]
pub enum Event {
    // <---- Put the tag is here, followed the union memory, 
    A(EventA),
    B(EventB),
}

extern {
    pub fn pollEvents(*mut Event);
}

pub fn poll_events(*mut Event) {
    unsafe {
        pollEvents(*mut Event);
    }
}

1 Ответ

0 голосов
/ 29 января 2019

Существует RFC , который гарантирует некоторую разметку при использовании #[repr(C, Int)] для перечисления, которое в основном позволяет то, что вы хотите.Обратите внимание, что, как всегда, Rust делает только лучшие предположения, и вы должны добавить тесты для разметки памяти во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...