![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| EvgeniyK77 |
|
||||||||
|
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 19.8.2006 Репутация: нет Всего: нет |
Подскажите, пожалуйста, как корректно разместить класс в статической библиотеке (.a)?
Поясню суть. Есть некоторый класс, который я скомпилировал в Linux с помощью mingw. Полученную библиотеку и заголовочный файл дал другому человеку, который её использовал в своей программе. Всё было здорово. Всё чудно линковалось и работало... До поры до времени. После очередного обновления mingw (у него) программа стала падать в одном из моих методов. При этом линковщик не ругался. После пересборки моей библиотеки на его машине падения прекратились. Стал разбираться. Оказалось, что mingw вдруг решил для методов поменять порядок аргументов (this поместил в другое место)! Я, конечно, понимаю, что классы в библиотеках - это не очень хорошо, т.к. разные компиляторы по-разному генерят имена для методов, и библиотека, собранная одним компилятором, может не подлинковаться другим. Но компилятор ведь один! Да и линковка прошла успешно... Быть может, есть какие-то стандартные способы, типа extern "C"? Если интересно, вот тест (библ. собрана на Fedora 14, а программа - на Fedora 17):
Программы выводит:
|
||||||||
|
|||||||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
this передаётся в регистре ECX, это конвенция thiscall и никаких вольностей компилятор тут позволять себе не должен. Порядок аргументов тоже определён thiscall. Проблема где-то в другом месте. Это сообщение отредактировал(а) Cheloveck - 15.8.2012, 10:11 -------------------- ![]() |
|||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
Это всего лишь соглашение, а не стандарт. И никто его поддерживать не обязан. Да и что делать на системах, в которых регистра ECX изначально не было? http://www.ownedcore.com/forums/world-of-w...in32-mingw.html EvgeniyK77, Я точно не знаю, но поидее надо или перекомпиливать все одним компилятором или использовать только cdecl С-функции, т.е. никакого C++ наверху торчать не должно. |
|||
|
||||
| EvgeniyK77 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 19.8.2006 Репутация: нет Всего: нет |
Спасибо!
Стал разбираться с модификаторами и узнал, что в mingw 4.7 умолчальный модификатор методов изменился на __thiscall. В 4.5 такого вообще нет. Если у метода явно поставить __fastcall, __stdcall или __cdecl, то всё работает! Какой из этих модификаторов предпочтительнее? |
|||
|
||||
| leniviy |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 552 Регистрация: 8.2.2003 Где: Спб Репутация: 1 Всего: 5 |
не мог бы ты приаттачить 2 версии тестовой либы? Одну собранную на старом MinGW, другую - на новом. Естественно, с -g -O0. По идее, у методов __cdecl и __thiscall должна быть разная сигнатура. Visual C++:
@@QAAXXZ vs @@QAEXXZ То есть, программа не должна была компилироваться. Это сообщение отредактировал(а) leniviy - 17.8.2012, 09:53 |
|||
|
||||
| EvgeniyK77 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 19.8.2006 Репутация: нет Всего: нет |
||||
|
||||
| leniviy |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 552 Регистрация: 8.2.2003 Где: Спб Репутация: 1 Всего: 5 |
спасибо. Похоже, что в mingw gcc сигнатура одинаковая.
Идеального нет. Я бы использовал __thiscall, так как он быстрее:
А на старом компиляторе пускай не собирается. Кто умеет ставить MinGW, сможет поставить и новый MinGW |
|||
|
||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Кто сказал, что классы в библиотеках - плохая идея? Не говорите таких глупостей.
GCC версии < 4.7 передает this через стэк. GCC версии >= 4.7 передает this через ecx на x86 платформах. Это сделано для обеспечения совместимости с MSVC либами. Другого не дано. Не нужно указывать никаких extern/__thiscall в статических либах. Зачем? Просто используйте оба компилятор или выше 4.6, или равный и ниже ему. Добавлено через 4 минуты и 9 секунд To leniviy: Вопрос насчет быстроты __thiscall спорный. Может, тогда fastcall еще быстрее? Однако, его никто не использует. Это сообщение отредактировал(а) Randajad - 17.8.2012, 13:06 |
|||
|
||||
| leniviy |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 552 Регистрация: 8.2.2003 Где: Спб Репутация: 1 Всего: 5 |
Это значит, оставить всё как есть. Лучше пускай программа валится на сборке, чем при работе. А для этого нужно, чтобы несовместимую библиотеку нельзя было подключить. До совместимости с MSVC далеко: имена C++ по-разному декорируются.
Здесь выбор только между двумя вариантами: cdecl и thiscall. |
||||
|
|||||
| Randajad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 15.3.2012 Репутация: 8 Всего: 8 |
Это все хорошо, но этот шаг сделан именно ради улучшения совместимости с MSVC. Такие "валы" видны сразу же при первом запуске. Виноват человек и пихать везде MYCALL - не решение проблемы.
Почему между двумя? Fastcall поддерживает классы тоже. Это сообщение отредактировал(а) Randajad - 17.8.2012, 14:45 |
|||
|
||||
| EvgeniyK77 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 19.8.2006 Репутация: нет Всего: нет |
На различия компиляторов я не думал, т.к. считал, что либа, в случае чего, просто не подлинкуется. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |