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 ответов

2 просмотра

Почему бы не брать параметр 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, ...

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

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

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

Комрады, посоветуйте, куда копать? Стал прикручивать кастомизацию тем. В OnShow главной главной формы пытаюсь загрузить из файла настроек и применить тему (на скрине, как долж...
Ed Doc
13
OnShow один раз вызывается? или возможен Hide?
Iluha Companets
14
Такс, блин, таки кто-то знает, каким образом работают макросы stdin/stdout/stderr? Я влез в stdio.h, там определения нет, отладил через асмокод - вызывается функция со странны...
The Bird of Hermes
18
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Всем привет, на линуксе лучше на fasm или nasm учиться писать для начала ?
meszjol
14
Если у меня есть такой класс: Object = {} function Object:new(a_name, a_transform, a_color, a_mesh, a_material, a_shader, a_textures) local private = {} private.n...
Cuarno Vile
4
Гайз, кто-нибудь пробовал запустить probe-rs под камень, которого нет в probe-rs? Мб есть какой-нибудь пример у кого... Через target-gen попробовал сгенерировать chip-descript...
Максим Смирнов
2
А еще в перле можно уже @arr1 + @arr2?
Sergei Zhmylove
53
@sand_witch скорее к тебе вопрос, добавил в .cabal webdriver-w3c и вот такая ошибка от nix develop error: Package ‘script-monad-0.0.4’ in /nix/store/7vdxbra0kwbr0ys0kc5...
Fedor
5
@MrMiscipitlick А можешь макрос написать, который будет вычислять смещение относительно переданных меток? Просто .label1-.label2, и вернуть значение.
КТ315
35
Карта сайта