![]() |
|
|
![]()
|
|
| SABROG |
|
||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: нет Всего: 91 |
Обнаружил интересную особенность. Например нам надо экспортировать класс в dllку. Но класс находится в сторонней .a библиотеке, которая линкуется с .exe файлом, то такой класс не экспортируется, его нет в .def файле на выходе с main.exe. Но если точно такой же класс находится внутри main.exe, то он прекрасно экспортируется и внутри дллки я могу вызывать операторы new и delete, при этом конструктор находится внутри exe файла и сообщение на экран выводится именно с него. Возможно проблема где-то зарылась в отсутствии файла реализации класса (.o), который не линкуется к .exe.
Вот мой пример: http://filebeam.com/ca9f86187ea6f8d26a363926ef7ac22a --- Хмм, получилось. Из .a тоже вызывается теперь, главное при сборке class.a, чтобы стоял __declspec(dllexport) и тоже самое должно быть в main.exe при сборке. Если бы например при сборке class.a класс стоял бы просто как обычный не экспортируемый, а потом в main.exe стал бы экспортируемым, то это не сработало бы. Соответственно в dll.dll при подключении заголовков классов должно быть __declspec(dllimport). А при экспорте функции из dll в exe __declspec(export). Теперь предстоит разобраться как разное построение классов влияет на экспорт (наследование, шаблоны, виртуальные функции) --- Век живи - век учись. При импорте класса даже не нужно прописывать __declspec(dllimport) оказывается... Забавно. Более того, там может остаться __declspec(dllexport) и это будет работать. Похоже смысл есть только в экспорте, либо он есть либо нет. А уж то что ты импортируешь определяется линковкой. Кстати интересно почему тройное экспортирование не вышло, цепочка завершилась на .dllке, как экспортировала 1 функции так и осталось. --- Еще одна особенность. Если использовать .def файл, то классы не находятся:
А связано это с тем, что классы и данные не нужно импортировать, они автоматически импортируются. Поэтому удалив из .def файла все кроме статическх функций все линкуется и работает. --- Еще кое-что раскопал. Оптимизация прямым образом влияет на список экспортируемых данных. Например неиспользуемые переменные вырезаются, тоже самое с функциями и классами. Отключив оптимизацию полностью я обнаружил, что "подтянулись" еще некоторые экспортируемые данные, на которые, до этого, были ошибки. Но полностью проблемы это не решило. А чтобы компилить с оптимизацией надо либо вспоминать волшебное слово volatile, либо прописывать всегда __declspec(dllimport). --- Нашел показательный пример как получить undefined reference, проверил, работает:
Причем в этом случае не помогает ни отключение оптимизации ни __declspec(dllexport). Помогает только наличие хоть какого-нибудь кода внутри конструктора и деструктора:
--- Продвинулся дальше. Выяснил, что если создать базовый класс без конструктора, потом унаследовать его и ввести конструктор, то получаем:
--- Еще в копилку. Если в классе определен метод/конструктор/деструктор, но нигде не определена реализация, даже в виде пустой "{}", то снова возникает проблема с линковкой. Это сообщение отредактировал(а) SABROG - 31.1.2008, 17:42 |
||||||||
|
|||||||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | GNU toolchain | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |