Может ли постоянная/статическая ржавчина подвергаться воздействию C?

Скажем, у меня есть Rust API, который содержит константу или статику, например i32. Я хочу использовать этот API Rust с C. С стороны C, я хочу использовать эту константу в качестве размера массива. Правильно ли, что нет способа сделать это? Является лучшим решением для переопределения константы в моих заголовочных файлах C, которые предоставляют декларации для остальной части Rust API?

Update: Чтобы быть более конкретным, я использую компилятор, который не поддерживает массивы переменной длины (Visual С++ 2005)

Ответ 1

Вы, безусловно, можете это сделать, по крайней мере, внутри функций:

cnst.rs:

#[no_mangle]
pub static X: i32 = 42;

cnstuse.c:

#include <stdint.h>
#include <stdio.h>

extern const int32_t X;

int main() {
    char data[X];
    printf("%lu\n", sizeof(data));
    return 0;
}

Компиляция:

% rustc --crate-type=staticlib cnst.rs
note: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: System
note: library: pthread
note: library: c
note: library: m
% gcc -o cnstuse cnstuse.c libcnst.a
% ./cnstuse
42

Объявления массива верхнего уровня, однако, не могут использовать глобальные переменные/константы для размера, поэтому это будет работать только внутри функций.

Ответ 2

Чтобы быть более конкретным, я использую компилятор, который не поддерживает массивы переменной длины (Visual С++ 2005)

Для этого требуется, чтобы константа была определена (а не просто объявлена) в точке использования. Кроме того, C имеет гораздо больше ограничений, чем С++, что является константой, используемой в качестве измерения массива: в основном целые литералы (которые могут быть заменены макросами) и счетчиками; в отличие от С++ он не имеет интегральных констант (int const x), поэтому в зависимости от режима (C или С++), который вы компилируете, вы можете быть ограничены.

В rustc или Cargo нет возможности автоматически генерировать файлы C, символы экспортируются и доступны только во время соединения, а не во время компиляции.


Вам повезло, хотя есть решение, хотя оно немного более громоздко.

Rust содержит файл build.rs, который компилируется и выполняется как часть обычного процесса компиляции. Этот файл может содержать команду для генерации других файлов, и поэтому вполне возможно:

  • Запишите константу раз и навсегда в файле .rs
  • Сгенерировать заголовок C "экспорт" этой константы в формате C через файл build.rs.