Есть библиотека написанная на C++, она состоит из набора .h файлов. Мне нужно иметь возможность вызывать их из Rust. Что я должен сделать для этого?
Как я понимаю, мне сначала нужно как-то скомпилировать весь C++ код библиотеки в .lib файл, а затем с помощью bindgen создать привязку к основному заголовочному файлу библиотеки, так?
Вся библиотека предположим состоит из трёх файлов: cool_lib.h - основной файл который должен включаться для использования библиотеки, cool_lib_iternals.h и cool_lib_other.h - включаются в cool_lib.h, используются как библиотекой для её нужд так и пользователем библиотеки.
Какие конкретные шаги стоит сделать для того, что-бы это заработало в Rust? На Windows.
mayton2019, читал, но не совсем понял как именно в моей ситуации действовать.
Собственно, должен ли я генерировать binding только к одному заголовочному файлу cool_lib.h или ко всем?
Скорее всего придётся сделать extern C обёртку над библиотекой и биндится уже с ней. Ну и надо понимать, что никакие абстракции плюсов вроде темплейтов, классов и т.д. в раст не протащить.
В какой-то степени может помочь cxx, но надо понимать, что эта штука тоже не всесильна.
правильно ли будет скомпилировать .h файлы в единую .lib и линковать её с Rust?
Если библиотека на шаблонах, то вы не сможете просто так ее скомпилировать, используя только одни заголовки этой библиотеки.
Потребуется написать код на С++, который будет инстанцировать нужные в Rustе шаблоны (объекты) и предоставлять их функционал для rust. И уже этот код собирать как свою библиотеку, а не исходную.
Имя, Инстанцирование - создание из шаблона реального оъекта подстановкой в шаблон реальных параметров.
В общем, если в заголовках библиотеки шаблоны, то вам надо написать код на С++, который эти шаблоны будет представлять в реальные объекты. И уже эти реальные объекты, созданные вашим кодом вы можете экспортировать в rust.
Т.е. шаблонный код - это абстракция, которая сама по себе скомпилироваться и исполняться не может. Но когда на основе этой абстракции будет сгенерирован реальный код/объект - его уже можно скомпилировать, выполнить и т.д. и т.п.
В С++ инстанцирование шаблонов происходит во время компиляции. Компилятор сам создает реальные объекты, подставляя в шаблон соответствующие параметры.
res2001, а если я создам C файл с функцией в которую вынесу нужный мне функционал библиотеки и буду компилировать этот .c файл в .lib, будет ли весь необходимый код(библиотеки) содержаться в .lib? Тогда будет проще вызывать Си функцию из Rust.
Имя, В Си нет шаблонов. Файл вы можете создать любой, компилятору в принципе все равно какое расширение у него будет. Но содержать он должен C++ код и компилятор надо использовать для С++.
Обычно компиляторы для Си и С++ разные. Разве что микросовтовский cl умеет и то и то, но там свои заморочки, т.к. официально он стандарты Си не поддерживает (по крайней мере в недалеком прошлом так было, давно уже в него не заглядывал), но Си код компилировать умеет.
Например в gcc надо использовать g++ для С++ кода и gcc для Си кода.
будет ли весь необходимый код(библиотеки) содержаться в .lib?
Если абстрагироваться от того, что вы пишете про Си, а нужно С++, то да, в полученной библиотеке на основе вашего кода + кода исходной библиотеки будет содержаться все что нужно. Точнее то что вы экспортируете, то там и будет содержаться.
Как выше было замечено экспортируемые функции должны быть объявлены как extern C - это директива С++, которая заставляет компилятор не использовать в объектном файле С++ расширения. Это позволяет использовать такую библиотеку в программах написанных практически на любой ЯПе, который умеет работать с Си библиотеками.
Т.е. снаружи ваша библиотека будет выглядеть как Си библиотека, хотя написана будет на С++.
а если я создам C файл с функцией в которую вынесу нужный мне функционал библиотеки
Перечитал тут ваш последний вопрос и возник встречный вопрос: что значит "вынесу"?
Скопирую из заголовка в .cpp файл какой-то участок кода библиотеки?
Это бесполезное занятие.
В .cpp файле вы должны написать код, который будет использовать шаблонный класс/функцию из библиотеки.
Т.е. это будет не код библиотеки, а ваш новый код.
Копи-паст тут не прокатит.
Подобная обертка для экспорта функционала обычно бывает очень простой, если не сказать элементарной - в вашей функции будет вызываться функция библиотеки, с соответствующими преобразованиями типов.
res2001, под "вынесу" я и подразумевал обёртку сишную на C++.
Собственно как раз назрел ещё один вопрос: Вот есть например тип использующий шаблоны и прочие C++ вещи, если я буду делать обёртку, то это должна быть функция выглядящая как Си функция, но компилироваться она должна же по прежнему как C++? Как вообще эта обёртка должна выглядеть что-бы в конечном итоге вызывать её как С функцию?