vault backup: 2025-11-17 19:12:21
This commit is contained in:
parent
c5a490c5d4
commit
1b9e3af5ce
9
4.2/1.md
9
4.2/1.md
@ -12,8 +12,8 @@
|
||||
- [x] Умеет импользовать bindgen и cc для генерации Rust API из Си header файлов
|
||||
- [x] Практика: сборка Си библиотеки (https://github.com/DaveGamble/cJSON).
|
||||
|
||||
- [ ] Прописать ОРы для глав
|
||||
- [ ] Придумать квизы
|
||||
- [x] Прописать ОРы для глав ✅ 2025-11-17
|
||||
- [x] Придумать квизы ✅ 2025-11-17
|
||||
|
||||
старт
|
||||
- [ ] Сначала практически расписать бест практис с с аби,
|
||||
@ -72,7 +72,8 @@ unsafe extern "C" {
|
||||
### Optional pointer (null optimization) - нужно ли?
|
||||
### Отделение взаимодействия с ffi в отдельный крейт
|
||||
Если вы пишете библиотеку, взаимодействующую с C ABI, отделяйте это взаимодействие в отдельный крейт (который обычно называют \*-sys). На это есть несколько веских {{причин}}[https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages]:
|
||||
- Несколько разных библиотек могут переиспользовать уже написанный код для взаимодействия с библиотекой
|
||||
- Несколько разных библиотек могут переиспользовать уже написанный код для взаимод
|
||||
- ействия с библиотекой
|
||||
- Так, одна и та же библиотека не будет собираться несколько раз и не будет слинкована несколько раз (то есть не будет существовать несколько разных или одинаковых версий библиотеки в бинаре)
|
||||
- Легкость изменения библиотеки, от которой зависит бинарь (версии, поиска ее пути и всей остальной конфигурации)
|
||||
|
||||
@ -259,7 +260,6 @@ fn main() {
|
||||
println!("cargo:rustc-link-lib=dylib=mylib");
|
||||
}
|
||||
```
|
||||
// update
|
||||
В cargo:rustc-link-lib передано значение dylib=mylib. Оно позволяет явно указать, что нужно подгрузить динамическую библиотеку (dylib) с название mylib (у такой библиотеки будет название libmylib.so на примере linux). Значение \[тип=] опционально и может быть одним из:
|
||||
- dylib - динамическая библиотека
|
||||
- static - статическая библиотека
|
||||
@ -415,7 +415,6 @@ int main() {
|
||||
clang main.c target/debug/libmylib.a -o ./a.exe
|
||||
```
|
||||
При запуске ./a.exe будет получен ожидаемый результат.
|
||||
// update
|
||||
Для crate-type возможны следующие значения:
|
||||
- staticlib - сборка статической библиотеки
|
||||
- dylib - сборка динамической библиотеки, предназначенной для использования в rust коде. Собираться использующий код и dylib должны одной и той же версией компилятора, так как у dylib нет стабильного интерфейса
|
||||
|
||||
14
4.2/2.md
14
4.2/2.md
@ -72,8 +72,13 @@ fn main() {
|
||||
}
|
||||
```
|
||||
У json обозначен не встречавшийся до этого тип `*mut _`
|
||||
## Указатели
|
||||
Вы уже неоднократно пользовались референсами в своем коде. В этих типах компилятор следит за временем жизни, чтобы не обратится к памяти после освобождения, а так же за валидностью памяти. Но, когда дело доходит до вызова внешней функции компилятор уже будет не способен отследить время жизни и валидность памяти.
|
||||
## Сырые указатели
|
||||
Вы уже неоднократно пользовались референсами в своем коде. В этих типах компилятор следит за временем жизни, чтобы не обратится к памяти после освобождения, а так же за валидностью памяти. Но, когда дело доходит до вызова внешней функции компилятор уже будет не способен отследить время жизни и валидность памяти. Поэтому в rust есть аналогичный тип - сырые указатели. Он унаследован по синтаксису и смыслу от своих предшественников (в частности от С), поэтому его описание выглядит так:
|
||||
`*const T` - для неизменяемого указателя на тип T
|
||||
`*mut T` - для изменяемого указателя на тип T
|
||||
Внутри себя он, точно так же, как и референс, содержит адрес на память и опционально метадату, но сырой указатель не дает абсолютно никаких гарантий по памяти. Это нетипично для rust, но так необходимо при взаимодействии с внешними функциями, так для них компилятор никак не может гарантировать безопасность.
|
||||
## Взаимодействие с сырым указателем
|
||||
Если же сырой указатель не дает
|
||||
|
||||
**Начать с проблемы, когда компилятор не может гарантировать безопасность по памяти (но без этого невозможно написать программу), возможно из ub**
|
||||
Допустим, на вход вашей функции
|
||||
@ -81,13 +86,18 @@ fn main() {
|
||||
**Рассказать про причины ub**
|
||||
- как в математике есть неопределенности (к примеру, для деления на ноль), так и в языках программирования тоже есть свои неопределенности.
|
||||
Именно для этого и было создана такая вещь, как неопределённое поведение.
|
||||
Неопределено, значит никогда не случается. Значит компилятор может оптимизировать код только соблюдая верность тех случаев, что не являются ub. (пример с nullptr дереф)
|
||||
|
||||
**Рассказать, чем является unsafe, ответственность на программисте, про ub (НЕ является избавлением от borrow checker)**
|
||||
|
||||
**Как про отдельную вещь рассказать про вызов unsafe функции**
|
||||
|
||||
**Рассказать про применение unsafe (взаимодействие с С, оптимизация (вспомнить небезопасную либу для бэкенда: rocket или actix), написание основы/базы языка)**
|
||||
|
||||
**Практика по пути**
|
||||
|
||||
**Мб рассказать про кейс с лайфтаймами**
|
||||
|
||||
|
||||
- [ ] Определении функции unsafe если соблюдение инвариантов висит на пользователе (при написании такой функции смотреть - является ли сам интерфейс функции safe)
|
||||
- [ ] примеры из third party
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user