2015-04-28 6 views
0

Я делаю некоторую Rust FFI работу для API Erlang NIF, и у меня есть эти:Raw указатель типа для интерьера изменчивой структуры

ErlNifEnv *enif_alloc_env(); 
void enif_free_env(ErlNifEnv* env); 

Этот указатель ErlNifEnv получает передается множество других функций, но пользователю никогда не будет обрабатывать указатель. Кроме того, этот указатель не является потокобезопасным (для использования нескольких потоков потребуется мьютекс). Наивный Rust представление этого типа будет ..

struct ErlNifEnv; 
*mut ErlNifEnv; 

Но, я думаю, что я могу относиться к этому типу, как имеющие «внутреннее переменчивость», который привел бы к ...

struct ErlNifEnv; 
*const ErlNifEnv; 

Должен ли я это лечение указатель как const, хотя базовый код C видит его как неконстантный?

ответ

2

Я лично считаю, что вы должны относиться к ним так же, как относитесь к ссылкам в самой ржавчине. Если для функции требуется ссылка &mut, весьма вероятно, что она фактически изменит значение, и если она потребует &, то естественно ожидать, что значение не будет изменено (конечно, без учета внутренней изменчивости).

C не имеет различия между унаследованной и внутренней изменчивостью, поэтому вы можете выбрать, что использовать *mut или *const исключительно на основе того, как функции C работают с этим значением. Фактически, в правильно написанном C API это различие будет присутствовать в виде квалификаторов const. Следовательно, если есть какие-либо функции, которые хотят изменить значение, перейдите к *mut. Если таких функций нет (например, это неизменяемая структура, созданная только один раз), переходите к *const. Это, конечно же, относится к типу, который вы хотите сохранить в вашей обертке - в подписях функций FFI вы всегда должны отображать подписи C API.