Как стать автором
Обновить

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

Спасибо за статью.
Решил посмотреть мнения других в комментариях, а их нет.
Видимо все в крайнем шоке и ужасе.
Сам в шоке, что почти сутки уже прошли, а коментов нет )
Классная статья спасибо.
Память отчистить я постоянно забываю.
Когда-то давно я писал на питоне в пхп: pecl.php.net/package/python
Тот еще изврат был, я вам скажу. Подход, предложенный в FFI, пока что выглядит лучше. Но, как говорится, будем посмотреть.
чего только не бывает на свете )
интересно а код на GO можно будет так подключить
НЛО прилетело и опубликовало эту надпись здесь
если в сигнатуре фунции есть какие-то Rust-специфичные типы данных, которых нет в Си, то да

Если чужой язык осилит сам распарсить C ABI то оберток не понадобится. Правда не слышал чтобы кто-то так делал c FFI

Маленькое замечание: в extern штуковинах, т.е. которые торчат "наружу", предпочтительнее использовать не i32 и подобные, а libc::size_t, libc::c_int и другие типы из пакета libc.

Спасибо, будем знать

Все базовые сишные типы определены в std::os::raw::*, таскать за собой целый libc во многих случаях не обязательно.
имхо еще один лишний слой: wasm
сейчас можно и напрямую

А по скорости не замеряли?

нет

Отличная статья, спасибо. Всех желающих рассказать, что раст это "сложный" язык который с беграундом Java/C#, а уж тем более PHP не осилить буду отправлять к вам.


К слову, чтобы не писать руками "дроп" а использовать растовую магию можно немног схитрить и таскать с собой указатель на структуру. Тогда с помощью mem::forget() можно сделать "утечку", а в destroy материализовать значение обратно, тогда правильный деструктор рекурсивно вызовется самостоятельно.


Пример такого можно глянуть здесь: https://github.com/nebgnahz/cv-rs/blob/master/src/lib.rs#L124-L142


Метод pack — это аналог вашего FFI, конвертация из Vec в Си-совместимый тип для передачи в FFI. Обратите внимание на строки 124-142 и 163-169. Ваш код побезопаснее, но требует написания ручного рекурсивного вызова деструктора.


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


P.S. Еще в расте приветствуется не пихать в unsafe-блок больше необходимого. Таким образом, ваш код можно чуть-чуть переписать в виде


#[no_mangle]
pub extern "C" fn parse_arithmetic(s: *const c_char) -> *mut ExpressionFfi {
  // todo: error handling
  let rust_string = unsafe { CStr::from_ptr(s).to_str().unwrap() };
  parse(rust_string).unwrap().convert_to_c()
}
Спасибо за комментарий! Всё по делу, всё полезно, довольно редко такие бывают на хабре.

> Всех желающих рассказать, что раст это «сложный» язык который с беграундом Java/C#, а уж тем более PHP не осилить буду отправлять к вам.
Справедливости ради замечу, что Rust все же сложный язык. Cложнее, чем Java или Go в несколько раз.

Кстати, туда же я положил docker образ, в котором есть PHP (скомпилированный с FFI)

Сложно у вас в РНР, в Perl бы ничего пересобирать не пришлось. Просто подключаете модуль и пользуетесь ;-)


Например FFI::Me

дело в том, что это еще альфа версия. Возможно, когда будет стабильная версия, ffi включат по-умолчанию.

Обычно нет проблем с модулями на php. Например, чтобы установить модуль pgsql достаточно просто написать (в убунте) apt install php-pgsql ну или как-то так
В PHP 7.4beta4 Ubuntu 16 почему-то выдаёт ошибку
Fatal error: Uncaught FFI\Exception: FFI API is restricted by «ffi.enable» configuration directive in /var/www/html/plain.local/index.php:10 Stack trace: #0 /var/www/html/plain.local/index.php(10): FFI::cdef() #1 {main} thrown in /var/www/html/plain.local/index.php on line 10


Хотя настройка стоит в true и в phpinfo() это видно. Баг?
Не знаю
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории