172 похожих чатов

Ищу какие-то пути обхода следующего ограничения: Есть указатель на функцию fn(A)

-> bool (это необязательно, есть определённая свобода выбора, впрочем пусть это будет стартовой точкой), нужно сделать из неё указатель на функцию fn(B) -> bool(это уже менять нельзя). Можно сконвертировать B в A, скажем A::from_b(b: B).

Попытка написать обёртку сразу же заканчивается неудачей:

fn convert(f: fn(A) -> bool) {
let f_new = move |b: B| f(A::from_b(b));
some_api(f_new) // облом, ожидался указатель на функцию, получили замыкание
}

Так вот, я размышляю над этой проблемой, одна сумасшедшая идея такая — определить f_new как generic функцию:

fn f_new<F>(b: B) -> bool {
let f = [указатель на старую функцию получить из F];
f(A::from_b(b)
}
Дело за малым — получить указатель на функцию из дженерик-параметра.

Есть ещё гипотетический способ передать через глобальный thread_local сторадж, но тоже возникает масса вопросов, как потом удалять указатели на функции, которые больше не нужны.

Для удобства, пример на плейграунде, (WARNING: сейчас не компилируется)
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d352c38adf255c5066ab4578cfdd6865

11 ответов

16 просмотров

Почему бы не брать параметр f: F? Еще, на найтли я бы попробовал фичу с названием типа unboxed_fn_traits, и тогда let f = |x| { assert_eq!(size_of::<F>(), 0;) F::call(unsafe{ &std::mem::zeroed() }, x)} по идее должно работатт

Mikail Bagishov
Почему бы не брать параметр f: F? Еще, на найтли ...

Можно и f: F, но тогда возникнет ещё дополнительная проблема, куда девать контекст.

Mikail Bagishov
Почему бы не брать параметр f: F? Еще, на найтли ...

fn convert_and_call<F: Fn(A) -> bool>(f: F) { let f_new = move |b: B| { F::call(&f, (A::from_b(b),)) // f(A::from_b(b)) }; some_api(f_new) } Ничего не поменялось в плане ошибки: также expected fn pointer found closure

Traveller Kolsky
Да и потом, вдруг F = !, тогда код unsound

Если брать f: F аргументом, то мы точно знаем что F населен и его инстансы можно создавать

Mikail Bagishov
Если брать f: F аргументом, то мы точно знаем что ...

А брать такой аргумент все равно придется, чтобы указать тип входной функции

𝙽𝚒𝚌𝚔 𝙻𝚒𝚗𝚔𝚎𝚛
fn convert_and_call<F: Fn(A) -> bool>(f: F) { le...

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

Alex Noname
Если обёртка для апи хочет через обычные функции к...

Но это не удобно с точки зрения пользователя. Каждый раз создавать пустую структуру с трейтом для этого

𝙽𝚒𝚌𝚔 𝙻𝚒𝚗𝚔𝚎𝚛
Да, я уже обозначил эти альтернативы.

Ещё одна: PR в библиотеку, чтобы был вариант API, принимающий указатель на контекст.

red75prime
Ещё одна: PR в библиотеку, чтобы был вариант API, ...

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

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта