Ответ 1
Я думаю, что вы объединяете два понятия. Строка должна быть repr(C)
, если вы хотите, чтобы макет структуры напрямую соответствовал макету структуры, поскольку компилятор C выложил бы ее. То есть, он имеет ту же самую информацию repr
в памяти.
Однако вам не нужно, если вы просто держите необработанный указатель и не собираетесь передавать холдинговую структуру обратно на C. Коротким решением в этом случае является "remove repr(C)
".
Объяснить немного больше об ошибке...
реализация Drop добавляет скрытое состояние в типы, возможно, конфликтует с
#[repr(C)]
Это обсуждалось в вопрос 24585. Когда объект отбрасывается, устанавливается скрытый флаг ( "состояние" ), который указывает, что объект был удален, предотвращая появление нескольких капель. Однако скрытые биты означают, что то, что вы видите в Rust, не соответствует тому, как бы выглядели байты структуры в C, отрицая цель repr(C)
.
Как cribbed from @bluss:
Программисты низкого уровня, не волнуйтесь: будущий Rust полностью удалит этот флаг кавычки.
и
Используйте
repr(C)
для передачи структур в FFI и используйтеDrop
в структурах "регулярного Rust", если вам нужно. Если вам нужны оба, вставьте структуруrepr(C)
внутри обычной структуры.
Представьте, что у нас была библиотека, которая предоставляет C-структуру с двумя 8-битными номерами и методы, которые принимают и возвращают эту структуру:
typedef struct {
char a;
char b;
} tuple_t;
tuple_t tuple_increment(tuple_t position);
В этом случае вы определенно захотите имитировать эту структуру и сопоставить представление C в Rust:
#[repr(C)]
struct Tuple {
a: libc::char,
b: libc::char,
}
Однако, если библиотека вернула указатели на структуру, и вам никогда не нужно в нее вставлять (структура непрозрачна), вам не нужно беспокоиться о repr(C)
:
void tuple_increment(tuple_t *position);
Затем вы можете просто использовать этот указатель и реализовать Drop:
struct TuplePointer(*mut libc::c_void);
impl Drop for TuplePointer {
// Call the appropriate free function from the library
}