Как я отмечал в другом вопросе SO, я наткнулся на эту статью. Проблема возникла, когда я скомпилировал boost 1.40 через MSVC7.1, и появилось несколько предупреждений C4251.

Теперь, после прочтения указанной статьи, я задаюсь вопросом: обычно ли не рекомендуется экспортировать код шаблона, например

class DLLEXPORT_MACRO AClass
{
public:
   std::vector<int> getVecCopy() { return myVec; }
   ...
}

Скажем, этот код скомпилирован в DLL через MSVC7.1. Хотя этот код не вызывает ошибок при ссылке из другого кода MSVC7.1, говорится, что ссылка на эту DLL в коде MSVC8 вызывает сбои во время выполнения (проблемы с выравниванием памяти?).

Поскольку это, очевидно, плохо ... как лучше всего справиться с проблемой экспорта кода шаблона?

1
msi 16 Окт 2009 в 17:57

2 ответа

Лучший ответ

Это кажется плохой идеей, поскольку std :: vector отличается или может отличаться в разных версиях компилятора. Однако это, скорее всего, может потерпеть неудачу во время загрузки, потому что изменение имени std :: vector должно различаться в разных версиях компилятора (это часть обоснования изменения имени).

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

Обратите внимание, что проблема не только в шаблонах. Представьте на мгновение, что std::string - это UDT вместо typedef, предоставляемый средой выполнения компилятора. Он все еще может меняться между версиями компилятора и, конечно, между поставщиками компиляторов. Его по-прежнему нельзя было бы использовать в интерфейсе DLL.

По этим причинам практические решения: 0. используйте C, 1. используйте COM или 2. остановитесь на одной версии компилятора.

6
MSalters 16 Окт 2009 в 18:20
3
Это аспект общих проблем C ++ ABI, из которых печально известная проблема «хрупкого базового класса» является другим частным случаем. Экспорт интерфейса шаблона из библиотеки DLL - это просто ожидающая катастрофа. Мое предпочтительное решение - вариант MSalters '0: вместо экспорта C ++ непосредственно из DLL, предоставьте тонкий слой экспорта с привязками C, с указателями объектов, передаваемыми клиенту взад и вперед в качестве непрозрачных дескрипторов. Таким образом, клиент не может напрямую обезвреживать внутреннее устройство объекта, зависящее от компилятора, поэтому у него не может быть этой проблемы.
 – 
Bob Murphy
16 Окт 2009 в 18:37
Спасибо за понимание. Хотя (1) не принимается во внимание, я думаю, что мог бы жить с (0) или (0 ') - как заявил Боб - соответственно. На самом деле, мне интересно, почему boost :: program_options создает «ожидающую катастрофу».
 – 
msi
17 Окт 2009 в 01:15

К сожалению, на самом деле нет возможности экспортировать код шаблона. Внешние библиотеки обычно просто предоставляют исходный код для любых шаблонов. Иногда у них есть шаблоны, использующие вспомогательные классы, которые не являются шаблонами, чтобы скрыть частный код. Но в принципе нет возможности сделать это.

0
rlbond 16 Окт 2009 в 18:17