#rust #dylib
#Ржавчина #dylib
Вопрос:
У меня есть основное приложение с кодом, который выглядит следующим образом:
pub fn load_lib() {
let dylib = libloading::Library::new("example.dylib") ...
unsafe { *dylib.get(b"fn_in_dylib") } ...
// calling function from dylib.
}
pub extern "Rust" fn fn_in_main_app() { ... } // Function that I want to call from dylib
example.dylib
dyliib успешно загружен, и функция из dylib вызывается без каких-либо проблем.
Но вот что я пытаюсь сделать внутри dylib:
pub extern "Rust" fn fn_in_dylib() {
fn_in_main_app(); // Here I'm trying to call function defined in main application.
}
extern "Rust" {
fn fn_in_main_app();
}
Но это даже не компилируется:
Undefined symbols for architecture x86_64:
"_fn_in_main_app", referenced from:
Я не уверен, что использую правильный способ реализации этого, поэтому меня не удивило, когда он не скомпилировался. Но я надеюсь, что это показывает, что я на самом деле пытаюсь.
Ответ №1:
Dylibs не могут зависеть от приложения, которое их загружает. График зависимостей dylib должен быть полностью линейным, циклические зависимости не допускаются. В зависимости от того, что вы делаете, может быть возможно перейти fn_in_main_app
к восходящей зависимости dylib. Вы также можете передать указатель на функцию в dylib:
pub extern "Rust" fn fn_in_dylib(fn_in_main_app: fn()) {
(fn_in_main_app)();
}
Комментарии:
1. Хорошо, это имеет смысл, теперь я пытаюсь передать указатель на функцию через статическую переменную. Хотя предложенный вами способ по-прежнему позволяет устанавливать статическую переменную через некоторую
init()
функцию, может быть, можно сделать статическую переменную «внешней»?2. Хорошо, кажется, невозможно объявить extern static . Я использовал статическую переменную в качестве указателя fn функцию extern init, которая присваивает фактический указатель функции статической переменной. Это работает.
3. В macOS есть понятие «пакетов», то есть плагинов, которые вы можете создавать, передавая
-bundle
компоновщику, и которые могут связываться с символами из основного исполняемого файла — но тогда, конечно, основной исполняемый файл не может связываться с символами из плагина.