Можно ли записать в указатель данных Rust, переданный из внешнего вызова функции, при доступе к указателю данных извне?

#rust #ffi

Вопрос:

Давайте предположим, что у нас есть программный модуль со структурой данных в Rust, который может выполнять определенные вычисления, используя список чисел в качестве входных данных. Мы хотели бы получить доступ к этому модулю извне, например, С . Поскольку вычисление обрабатывается номер за номером и каждый шаг требует времени, мы хотели бы подсчитать, сколько номеров списка было обработано до сих пор. Это хранится внутри внутренней переменной структуры данных.

Возьмем, например, следующий исходный код в Rust:

 pub struct Calculator {
  result: i32,
  steps: usize,
}

impl Calculator {
  pub fn new() -> Self {
    Calculator {
      result: 0, 
      steps: 0
    }
  }

  pub fn specific_computation(amp;mut self, numbers: Vec<f32>) {
    for number in numbers.into_iter() {
      // computation here
      self.steps  = 1;
    }    
  }
}
 

Теперь мы хотели бы разработать интерфейс внешней функции для запуска этого вычисления извне. Поскольку вычисление требует времени, мы также хотели бы знать, сколько чисел было обработано во время выполнения вычисления.

 #[no_mangle]
pub unsafe extern "C" fn create_calculator(calculator: amp;mut *mut Calculator) {
  *calculator = Box::into_raw(Box::new(Calculator::new()));
}

#[no_mangle]
pub unsafe extern "C" fn do_specific_computation(calculator: *mut Calculator, numbers: *const u32, count: i32) -> f32 {
  let numbers = std::slice::from_raw_parts(numbers as *const f32, count as usize);
  let calculator = amp;mut *calculator;
  calulator.specific_computation(numbers);
}
 

Можно ли получить доступ к указателю calculator извне во время выполнения вызова внешней функции specific_computation , чтобы calculator.steps можно было считывать внутреннюю переменную?

Комментарии:

1. Если вычисление выполняется, то поток блокируется, и вы ничего не можете сделать. Если вы хотите что-то сделать, затем создайте отдельный поток для выполнения вычислений (вы также можете переключиться usize на AtomicUsize ).

2. Спасибо вам за понимание! Основываясь на вашем ответе, я не уверен, что ясно выразился. Идея заключается в следующем: пока вычисление выполняется из внешнего вызова do_specific_computation , я хотел бы получить доступ к Calculator переданному объекту и прочитать его внутреннюю переменную steps . Мне ясно, что для этого мне нужно создать отдельный поток. Мне неясно, действительно ли я могу Calculator так легко получить доступ к объекту во время работы функции do_specific_computation .