идеи для распространения варианта или результата на код C - PullRequest
3 голосов
/ 03 августа 2020

Написание большой библиотеки, которая будет вызываться из C# через c interop. Попытка получить хороший чистый интерфейс с самого начала.

Интересно, есть ли у кого-нибудь идеи для распространения Option или Result на c вызывающих абонентов. Мне нравится ржавчина, и я хотел бы по возможности перенести эту семантику.

1 Ответ

2 голосов
/ 03 августа 2020

На основании комментария Stargateur вы можете использовать некоторые комбинации repr(C) структуры и объединения. Из-за некоторых ограничений на union мы требуем, чтобы базовые типы реализовали Copy.

#[repr(C)]
union COptionEnum<T>
where
    T: Copy,
{
    value: T,
    none: (),
}

#[repr(C)]
struct COption<T>
where
    T: Copy,
{
    discriminant: u32,
    value: COptionEnum<T>,
}

Однако они не особенно эргономичны c, поэтому, чтобы облегчить боль, вы можете предоставить преобразования в и с Option. Они выглядят так:

impl<T> From<Option<T>> for COption<T>
where
    T: Copy,
{
    fn from(v: Option<T>) -> COption<T> {
        match v {
            None => COption {
                discriminant: 0,
                value: COptionEnum { none: () },
            },
            Some(v) => COption {
                discriminant: 1,
                value: COptionEnum { value: v },
            },
        }
    }
}

impl<T> From<COption<T>> for Option<T>
where
    T: Copy,
{
    fn from(v: COption<T>) -> Option<T> {
        match v.discriminant {
            0 => None,
            1 => Some(unsafe { v.value.value }),
            _ => panic!("Invalid COption"),
        }
    }
}

Наконец, вы можете использовать их относительно безболезненно.

#[repr(C)]
#[derive(Copy, Clone)]
struct AType {
    a: i32,
    b: u64,
}

fn main() {
    let v1 = Some(AType { a: 1, b: 2 });
    let cv1: COption<AType> = v1.into();
    let w1: Option<AType> = cv1.into();
}

Полная копия находится на игровой площадке

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