Я разрабатываю библиотеку, которая работает с файлами PE для 32- и 64-разрядных архитектур. Некоторые структуры будут ссылаться как на виртуальные адреса (VA, например, ImageBase
), так и на относительные виртуальные адреса (RVA, например, смещение секции), например:
type VA32 = u32;
type RVA32 = i32;
struct Header32 {
image_base: VA32,
section_offsets: Vec<RVA32>,
}
let hdr = Header32 { /* ... */ };
При работе с 32-битными файлами PE виртуальный компьютер должен быть 32-битным и без знака, а RVA должен быть 32-битным и подписанным. Для 64-битных файлов PE оба типа должны быть 64-битными.
Я бы хотел, чтобы мои структуры использовали соответствующую ширину для этих типов, возможно, сделав их общими:
struct Header<VA, RVA> {
image_base: VA,
section_offsets: Vec<RVA>,
}
type VA32 = u32;
type RVA32 = i32;
let hdr: Header<VA32, RVA32> = Header { /* ... */ };
Но VA32
всегда идет только с RVA32
, а VA64
должен быть только с RVA64
. Есть ли идиоматический способ, которым я могу выразить это?
Используя полностью составленный синтаксис, я хочу сделать что-то вроде:
struct Header<Arch> {
image_base: arch.VA,
section_offsets: Vec<arch.RVA>,
}
type Arch32 = { VA: u32, RVA: i32 }
let hdr: Header<Arch32> = Header { /* ... */ };