Обновление до g ++ 4.7 (с поддержкой c ++ 11): какая-либо несовместимость ABI?

В 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 () ()

2

Решение

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 чуть больше …

4

Другие решения

Я продавец (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 *.

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

3

По вопросам рекламы [email protected]