Вызов библиотечной функции с помощью rust-abi - PullRequest
1 голос
/ 19 июня 2020

У меня есть пара ящиков X и Y. Первый управляет низкоуровневыми вещами и определяет точку входа. Затем он должен передать управление Y, который выполняет лог c высокого уровня. Я хотел бы явно объявить функцию Y в X и вызвать ее (чтобы компоновщик соединял их при создании Y-ящика).

Я знаю, что Rust имеет нестабильный ABI, но я использую оба этих ящика в одном рабочая область с тем же компилятором.

Я пробовал использовать следующий пример, но компоновщик не может найти real_main (неопределенная ссылка ...):

// X's main.rs
#[link(name = "y_lib_name", link = "static")]
extern "Rust" {
    fn real_main();
}

fn main() {
    // is it possible to avoid unsafe here, btw?
    unsafe { real_main() }
}


// Y's lib.rs
pub fn real_main() { .. }

Хотя символ существует:

$ nm target/debug/deps/liby_lib_name-8ade2b95fe4044c6.rlib | rg real_main
nm: lib.rmeta: file format not recognized
0000000000000000 T _ZN8y_lib_name9real_main17h8664760a5d2676beE

Думаю, мою проблему можно решить с помощью макроса в X, например:

// in X
#[macro_export]
macro_rules define_ep! {
  ($fn:expr) => {{ fn main() { $fn(); } }}
}


// in Y
fn f() {}

X::define_ep!(f);

, но я бы предпочел способ с поддержкой компоновщика, потому что:

  • если вы забыли компоновщик, выдает ошибку;
  • (не уверен) компоновщик выдает ошибку, если символы появляются более одного раза.
...