Я создаю DLL из группы статических библиотек, и у меня возникает проблема, когда экспортируются только части классов.
Я делаю объявление всех символов, с которыми я хочу экспортироватьопределение препроцессора, например:
#if defined(MYPROJ_BUILD_DLL)
//Build as a DLL
# define MY_API __declspec(dllexport)
#elif defined(MYPROJ_USE_DLL)
//Use as a DLL
# define MY_API __declspec(dllimport)
#else
//Build or use as a static lib
# define MY_API
#endif
Например:
class MY_API Foo{
...
}
Затем я создаю статическую библиотеку с неопределенным MYPROJ_BUILD_DLL
& MYPROJ_USE_DLL
, вызывающим создание статической библиотеки.
В другой сборке я создаю DLL из этих статических библиотек.Поэтому я определяю MYPROJ_BUILD_DLL
, чтобы все символы, которые я хочу экспортировать, были приписаны __declspec(dllexport)
(это делается путем включения всех заголовков статической библиотеки в исходный файл проекта DLL).
Редактировать: Примечание по неподтвержденным символам: параметры компоновщика Установлены для хранения данных без ссылок (/OPT:NOREF
) и Не удалять избыточные КОМДАТЫ (/OPT:NOICF
), так что никакие символы без ссылок не будут удалены.
Хорошо, теперьк проблеме.Когда я использую эту новую DLL, я получаю неразрешенные внешние данные, потому что экспортируются не все символы класса.Например, в таком классе:
class MY_API Foo{
public:
Foo(char const* );
int bar();
private:
Foo( char const*, char const* );
};
Только Foo::Foo( char const*, char const*);
и int Foo::bar();
экспортируется.Как это может быть?Я могу понять, отсутствовал ли весь класс, например, из-за того, что я забыл включить заголовок в сборку DLL.Но это только частично отсутствует.
Также, скажем, если Foo::Foo( char const*)
не было реализовано;тогда сборка DLL будет иметь неразрешенные внешние ошибки.Но сборка в порядке (я также дважды проверил объявления без реализации).
Примечание: Совокупный размер статических библиотек, которые я объединяю, составляет около 30 МБ, аПолученная DLL имеет размер 1,2 МБ.
Я использую Visual Studio 9.0 (2008) для сборки всего.И Зависит для проверки экспортируемых символов.
Редактировать: Для тех, кто задается вопросом, почему я не просто собираю DLL из каждой статической библиотеки: Iне могу, потому что они перекрестно ссылаются друг на друга (поэтому мне нужно сгруппировать их в одну DLL).Я знаю, это ужасно, я не могу понять логику этого.