Вопрос

Допустимо ли разработать DLL на C++, которая возвращает общие указатели повышения и использует их в качестве параметров?

Итак, можно ли экспортировать подобные функции?

1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);

В особенности:Работает ли подсчет ссылок за пределами границ DLL или требуется, чтобы exe и dll использовали одну и ту же среду выполнения?

Цель состоит в том, чтобы преодолеть проблемы с владением объектом.Таким образом, объект удаляется, когда dll и exe больше не ссылаются на него.

Это было полезно?

Решение

По словам Скотта Мейерса в «Эффективном C++» (3-е издание), «shared_ptrs» безопасны за пределами границ dll.Объектshared_ptr хранит указатель на деструктор из dll, которая его создала.

В своей книге в пункте 18 он заявляет: «Особенно хорошая особенность tr1 :: shared_ptr заключается в том, что он автоматически использует свой Deleorter для устранения еще одной потенциальной ошибки клиента,« Проблема Cross-DLL ». Эта проблема возникает, когда Объект создается с использованием новой в одной динамически связанной библиотеке (DLL), но удаляется в другой DLL.На многих платформах такие новые/удаленные пары Cross-Dll приводят к ошибкам времени выполнения.tr1 :: shared_ptr Избегайте проблемы, потому что его Daleter использует Delete из того же DLL, где создается tr1 :: shared_ptr ».

Однако у Тима Лешера есть интересная особенность, о которой он упоминает. здесь.Вам необходимо убедиться, что DLL, создавшая общий_ptr, не выгружена до того, как общий_ptr окончательно выйдет из области действия.Я бы сказал, что в большинстве случаев на это не стоит обращать внимание, но если вы создаете слабосвязанные библиотеки DLL, я бы рекомендовал не использоватьshared_ptr.

Еще одним потенциальным недостатком является необходимость создания обеих сторон с использованием совместимых версий библиотеки boost.Shared_ptr Boost уже долгое время работает стабильно.По крайней мере с тех пор 1.34 он совместим с tr1.

Другие советы

По моему мнению, если этого нет в стандарте и не является объектом/механизмом, предоставляемым вашей библиотекой, то он не должен быть частью интерфейса библиотеки.Вы можете создать свой собственный объект для подсчета ссылок и, возможно, использовать boost, но он не должен быть явно представлен в интерфейсе.

Библиотеки DLL обычно не владеют ресурсами — ресурсы принадлежат процессам, использующим DLL.Вероятно, вам лучше вернуть простой указатель, который затем сохраните в общем указателе на вызывающей стороне.Но без дополнительной информации трудно быть уверенным в этом на 100%.

На что следует обратить внимание, если вы предоставляете необработанные указатели из интерфейса dll.Это заставляет вас использовать общую dll CRT, память, выделенная в одном CRT, не может быть освобождена в другом CRT.Если вы используете общую dll CRT во всех своих модулях (dll и exe), тогда все в порядке, все они используют одну и ту же кучу, если вы этого не сделаете, вы пересечете CRT, и мир рухнет.

Помимо этого вопроса, я согласен с принятым ответом.Фабрика создания, вероятно, не должна определять владение и управление жизненным циклом клиентского кода.

Нет это не так.

Расположение boost::shared_ptr<T> может быть разным по обе стороны границы DLL.(На макет влияет версия компилятора, директивы упаковки и другие параметры компилятора, а также фактическая версия исходного кода Boost.)

Только типы «стандартного макета» (новая концепция в C++11, связанная со старой концепцией «POD = простые старые данные») могут безопасно передаваться между отдельно созданными модулями.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top