#windows #rust #dllimport
#Windows #Ржавчина #dllimport
Вопрос:
Я экспериментирую с Rust в Windows. Мой код объявляет и вызывает функцию во внешней библиотеке.
Объявление выглядит следующим образом:
#[link(name = "Rvea0326nc-64")]
extern "C" {
fn WeibullSpeedProbability(wa: amp;f32, wk: amp;f32, qu: amp;f32, prob: amp;f32, theerr: amp;i32) -> ();
}
(Это все по ссылке, потому что DLL — это Fortran. Он создан с помощью компилятора Intel.)
Обратите внимание, что имя файла не имеет расширения. Библиотека DLL находится в папке target debug deps проекта Rust.
Согласно документации здесь https://doc.rust-lang.org/std/keyword.extern.html , это должно импортировать DLL в Windows, но я получаю сообщение об ошибке, таким образом:
error: linking with `link.exe` failed: exit code: 1181
<SNIP>
= note: LINK : fatal error LNK1181: cannot open input file 'Rvea0326nc-64.lib'
Конечно же, если я найду и скопирую в файл *.lib, из которого была сгенерирована DLL, все будет работать нормально. Библиотека DLL, по-видимому, не имеет значения.
Я попытался явно добавить «.dll» к имени ссылки, но Rust просто жалуется, что не может найти Rvea0326nc-64.dll.lib.
Документация неверна? Я что-то пропустил? Есть ли способ заставить Rust работать с DLL?
Обновление: Я обнаружил, что при непосредственном запуске скомпилированного Rust исполняемого файла требуется DLL, а библиотека LIB — нет.
Ответ №1:
Не имея слишком большого опыта работы с FFI в Rust, я могу предположить, что для компиляции вашей программы вам понадобится .lib
установленная на вашем компьютере, чтобы rustc мог корректно проверить правильность функции FFI. Затем, когда выполняется созданный двоичный файл, он загружает .dll
во время выполнения и использует его.
Попробуйте посмотреть, сможете ли вы после создания двоичного файла с .lib
установленным, запустить этот двоичный файл без .lib
установленного.
Комментарии:
1. Спасибо. Ваша интуиция абсолютно верна. Библиотека необходима во время компиляции, но DLL необходима во время выполнения. C тоже похож на это, поэтому я должен был с этим разобраться. В основном я работаю с другими клиентскими языками, которые успешно компилируются с самой DLL (но затем завершаются сбоем во время выполнения, если вы допустили ошибку в объявлении импорта).
2. Я думаю, нам нужен переключатель / метод, чтобы заставить компилятор принимать среду только *.dll. У меня есть *.dll, куда мы не экспортируем файл *.lib, поэтому единственный способ, которым я мог бы создать это, — это внутренняя сборка. Наши клиенты не получают файлы * .lib, только файлы *.dll и не смогут ссылаться на эти API, если я не смогу создать фиктивные объекты *.lib, возможно, с помощью bindgen. (Необходимо исследовать.. Я новичок) Я ожидаю, что bindgen — это то, как это делается.