Можно ли экспортировать функцию из библиотеки dll rust, которая принимает ссылку в качестве параметра

#rust

Вопрос:

Я новичок в изучении rust и увидел, что rust использует общие периоды жизни для проверки ссылок во время компиляции, что очень приятно. Я не очень много копался в создании dll или общей библиотеки в rust, но из того, что я видел, функцию можно экспортировать из dll (как в c ). Но если я хочу экспортировать функцию, которая принимает ссылку в качестве параметра или возвращает ссылку, отличную от статических ссылок, как это будет работать ? библиотека dll и приложение не находятся в одном проекте, поэтому компилятор не может проверить время жизни в этом случае, так что это просто невозможно, например, экспорт шаблонных функций в c невозможен без создания экземпляра, но я не знаю, как создать экземпляр универсальной функции времени жизни в rust.

Зачем задавать этот вопрос ? rust нацелен на то, чтобы быть системным языком программирования, и общие библиотеки обязательны в любой системе, так как система, встроенная в rust, будет предоставлять свой api в чистом виде rust, не проходя через c ?

В c это возможно, как и в c :

 struct some_type_c
{
  int i;
  float f;
  void* p;
};

// vary between windows and unix likes
#define EXPORT some_platform_export

EXPORT void use_some_type_c(some_type_c* s) {   s->i; }

struct some_type_cpp
{
  int i;
  float f;
  void* p;
  
  // may be implemented in a cpp file
  EXPORT void use() {   i; }
};
 

Комментарии:

1. Я тоже новичок, но я бы предположил, что это должно быть в небезопасном блоке, так как rust не может проверить использование памяти / время жизни указателя во время компиляции, потому что он ничего не знает о вызывающем. Так что этого следует избегать, если это вообще возможно.

Ответ №1:

Поскольку у rust нет стабильного ABI, экспортируемые функции должны проходить через ABI C и по пути иметь дело с необработанными указателями.

При использовании языка C обычной практикой является создание более эргономичных функций, которые обертывают базовые небезопасные вызовы FFI (интерфейс внешних функций) и имеют правильные аннотации времени жизни для представления взаимосвязи между различными ссылками.

Ящики, которые динамически загружают системные библиотеки, часто состоят из двух ящиков, один с -sys суффиксом , содержащий привязки FFI, и более эргономичная версия (например openssl , зависит от openssl-sys , содержит сгенерированные C-совместимые типы, использование bindgen ).

При экспорте функций время жизни ссылок теряется при преобразовании их в необработанные указатели.

Однако стоит отметить, что все ящики rust статически связаны во время компиляции, и проверки срока службы выполняются через границы ящиков.