Как я могу получить значение const во время компиляции? - PullRequest
0 голосов
/ 01 февраля 2019

Моя цель - создать C API, в котором пользователь должен предоставить блок памяти определенного размера.Этот размер соответствует размеру структуры в моей библиотеке ржавчины, и поэтому я хотел бы извлечь размер структуры ржавчины и поместить ее в файл заголовка в виде макроса C.

Проблема в том,что я кросс-компилирую свою библиотеку, поэтому я не могу запустить на своем компьютере программу, которая печатает core::mem::size_of::<MyStruct>().Но я могу сохранить это значение в переменной const в моей библиотеке.

Есть ли способ извлечь значение этой переменной const, представляющее размер моей структуры во время компиляции, чтобы я мог затемвставить его в заголовочный файл C?

1 Ответ

0 голосов
/ 01 февраля 2019

Определенно выполните , а не . Сделайте это:

  1. В новом ящике импортируйте нужный тип и создайте функцию, которая возвращаетего размер:

    #[no_mangle]
    pub fn size_of_mystruct() -> usize {
        std::mem::size_of::<MyStruct>()
    }
    
  2. Получите выход LLVM-IR:

    CARGO_INCREMENTAL=0 cargo rustc -- --emit=llvm-ir -o ir
    

    Обязательно добавьте также опцию --target.Это создаст несколько файлов, один из которых должен иметь расширение .ll.CARGO_INCREMENTAL=0 важен - без него он создаст много файлов .ll, и кто знает, какой из них правильный!Откройте файл и найдите size_of_mystruct.Вы найдете что-то вроде этого:

    ; Function Attrs: uwtable
    define i64 @size_of_mystruct() unnamed_addr #0 !dbg !142 {
    start:
    ; call core::mem::size_of
      %0 = call i64 @_ZN4core3mem7size_of17hc5e3caf4d8826b98E(), !dbg !144
      br label %bb1, !dbg !144
    
  3. Поиск вызываемой здесь внутренней функции.(В данном случае _ZN4core3mem7size_of17hc5e3caf4d8826b98E).Это будет выглядеть так:

    ; core::mem::size_of
    ; Function Attrs: inlinehint uwtable
    define internal i64 @_ZN4core3mem7size_of17hc5e3caf4d8826b98E() unnamed_addr #1 !dbg !67 {
    start:
      %tmp_ret = alloca i64, align 8
      store i64 40, i64* %tmp_ret, align 8, !dbg !87
      %0 = load i64, i64* %tmp_ret, align 8, !dbg !87
      br label %bb1, !dbg !87
    
  4. Это важный бит: store i64 40.Структура составляет 40 байтов!

  5. Автоматизируйте процесс!

  6. Подождите, пока весь процесс таинственно прервется.

...