В Windows, при использовании g ++ 4.6 (mingw) и -std = c ++ 0x и связывании со сторонней статической библиотекой (которая была предоставлена поставщиком для использования с mingw), приложение работает нормально. Когда я переключился на g ++ 4.7.2 (mingw), чтобы я мог использовать -std = c ++ 11, приложение прекрасно работает, но при запуске вылетает. Если я закомментирую звонки в предоставленную поставщиком библиотеку, то она не вылетает. Я спросил службу поддержки поставщика библиотеки и мне сказали, что это не поддерживается.
Мой вопрос: есть ли какие-либо несовместимости ABI при переходе на более новую версию компилятора g ++? Разве это не обратно совместимо? Разве новые версии компилятора не должны работать с существующими и унаследованными сторонними статическими библиотеками?
Обратите внимание, что это происходит только на платформе Windows (mingw). Отлично работает на Linux.
Я добавил больше информации по этому вопросу:
Кто-нибудь использовал MinGW C ++ (статические) библиотеки Chilkat в приложении Windows, исходный код которого скомпилирован с g ++ 4.7.2 с опцией компиляции -std = c ++ 11? Приложение аварийно завершает работу при доступе к API Chilkat (например, создается объект CkString). Отлично работает на g ++ 4.6.2 (где я использую std = c ++ 0x).
На Linux с g ++ 4.7.2 эта программа работает нормально. Если при переходе с 4.6.2 на 4.7.2 возникает несовместимость ABI, то она не должна работать и в Linux, верно? Почему статическая библиотека chilkat-9.3.2 / lib / libchilkat.a, созданная поставщиком для использования с MINGW, должна быть осторожна, если остальная часть программы скомпилирована с использованием новейшего компилятора g ++ — это специфическое изменение MINGW в ABI?
#включают <windows.h> #включают <stdio.h> #включают <CkString.h> int main (int argc, char * argv []) { printf ("тест чилкат \ n"); CkString str1; printf ("тест завершен \ n"); }
gdb -i = mi test_chilkat.exe Запуск программы: test_chilkat.exe [Новая тема 4704.0x1a44] Программа получила сигнал SIGSEGV, Ошибка сегментации. 0x00404442 в CkObject :: CkObject () ()
MinGW 4.6.2 определенно генерирует другой код для вызова CkString
Конструктор, чем 4.7.2.
Вот командная строка, которую я использовал для компиляции вашей тестовой программы в файл кода сборки (где ./include
расположение заголовков чилкатов):
g++ -I ./include -S -masm=intel -std=gnu++0x test.cpp
Вот аннотированные разборки, записанные двумя printf()
звонки (которые GCC генерирует как puts()
звонки).
4.6.2:
call _puts
lea eax, [esp+28] ; eax gets pointer to `str1` being constructed
mov DWORD PTR [esp], eax ; put the `str1` pointer on the stack
call __ZN8CkStringC1Ev ; call `CkString::CkString()` ctor
mov DWORD PTR [esp], OFFSET FLAT:LC1
call _puts
4.7.2:
call _puts
lea eax, [esp+28] ; eax gets pointer to `str1` being constructed
mov ecx, eax ; ecx gets `str1` "this" pointer
LEHB0:
call __ZN8CkStringC1Ev ; call `CkString::CkString()` ctor
mov DWORD PTR [esp], OFFSET FLAT:LC1
call _puts
Как вы можете видеть, 4.6.2 передает указатель «this» конструктору в стеке (чего ожидает библиотека Chilkat). 4.7.2 передает указатель «this» в ecx
,
Похоже, начиная с 4.7.0. MinGW изменил соглашение о вызовах членов класса C ++ на __thiscall
, Увидеть http://mingw-users.1079350.n2.nabble.com/MinGW-GCC-4-7-0-released-td7578133.html
Похоже, вы можете изменить это значение по умолчанию, используя -mabi=sysv
опция, которая заставляет вашу тестовую программу работать на меня:
C:\temp>g++ --version
g++ (GCC) 4.7.2
...
C:\temp>g++ -mabi=sysv -I ./include -g -Wl,--enable-auto-import test.cpp -o test.exe libchilkat-9.3.2.a
C:\temp>test
test chilkat
test done
Тем не менее, вы, вероятно, будете покупать себе больше проблем с другими библиотеками в более сложных программах — например, вам почти наверняка потребуется пересобрать libstdc++.a
по крайней мере.
Я бы попросил разработчика Chilkat для библиотеки 4.7.x чуть больше …
Я продавец (Chilkat), и ответ Бабу был не в том, что он «не поддерживается», а в том, что «еще не поддерживается».
Между каждым выпуском Chilkat неизбежно появляются новые системы, которые нуждаются в поддержке. Каждый из них требует времени (в Чилкате) для создания автоматизированных систем для сборки и распределения. Быть на переднем крае чего-то нового и ожидать, что Chilkat немедленно его поддержит, несколько неразумно.
В настоящее время Chilkat планирует поддержку следующих новых систем: Windows Phone 8, Embarcadero XE3, Mono (кроссплатформенный для Windows, Linux, MAC OS X, iOS, Android и т. Д.), Любых новых версий Perl, Python, PHP и т. Д., Например, Python 3.3.0, Android для MIPS и x86. Chilkat также должен предоставлять API другими способами, которые не обязательно являются «новыми», такими как предоставление функциональной библиотеки DLL / .so / .dylib способом, подобным API «C».
В рамках рациональности кроссплатформенного API ведется значительная внутренняя разработка. Например, заголовки и реализации «Ck *» C ++ будут полностью сгенерированы. То же самое касается заголовков и реализаций, управляемых сборкой .NET, каждая из которых обращается к одним и тем же внутренним реализациям. Это будет делать две вещи: (1) устранять любые несоответствия между платформами и (2) позволять вносить улучшения / изменения во внешний слой. Например, если необходимо добавить модификатор соглашения о вызовах к каждому из методов класса C ++. Возможно добавление «_стандартный вызов «или»_chilkat_call «, где» __chilkat_call «может быть определен в одном месте, чтобы быть либо ничем,» _стандартный вызов «или»_thiscall «поможет. Это станет возможным, когда будут сгенерированы заголовки и методы Ck *.
Таким образом, ваша потребность будет поддержана в ближайшие месяцы, но не в данный момент. Я прошу прощения за это, но я надеюсь, что вы понимаете.