2012-10-27 2 views
2

Windows에서 g ++ 4.6 (mingw) 및 -std = C++ 0x를 사용하고 (mingw와 함께 사용하기 위해 공급 업체에서 제공 한) 제 3 자 정적 라이브러리와 연결하면 응용 프로그램이 올바르게 작동합니다. 내가 g-4.7.2 (mingw)로 바꿔서 -std = C++ 11을 사용할 수있게되었을 때, 응용 프로그램은 잘 만들었지 만 실행할 때 충돌이납니다. 공급 업체가 제공 한 라이브러리에 대한 호출을 주석 처리하면 충돌이 발생하지 않습니다. 라이브러리 공급 업체에 대한 고객 지원을 요청했고 이것이 지원되지 않는다고 들었습니다.g ++ 4.7로 업그레이드 (C++ 11 지원) : 모든 ABI 비 호환성?

최신 버전의 g ++ 컴파일러로 갈 때 내 질문에 "ABI 비 호환성이 있습니까?" 이전 버전과 호환되지 않습니까? 최신 버전의 컴파일러가 기존 및 기존 타사 정적 라이브러리에서 작동하지 않습니까?

Windows (mingw) 플랫폼에서만 발생합니다. 리눅스에서 잘 작동합니다.

나는이에 대한 자세한 정보를 추가했습니다 :

사람이 Chilkat의는 MinGW C++ 소스 g로 컴파일 ++ 4.7.2 = C++ (11) 컴파일 옵션 -std와 Windows 응용 프로그램에서 정적 라이브러리를 사용 했습니까? Chilkat API에 액세스하면 앱이 충돌합니다 (예 : CkString 객체가 인스턴스화 됨). g ++ 4.6.2에서 잘 작동합니다 (여기서 std = C++ 0x를 사용합니다). g ++ 4.7.2 Linux에서이 프로그램은 정상적으로 작동합니다. 4.6.2에서 4.7.2로 이동할 때 ABI 비 호환성이 있다면 Linux에서도 작동하지 않아야합니다. 맞습니까? 정적 라이브러리 chilkat-9.3.2/lib/libchilkat.a가 MINGW 치료에 사용하기 위해 벤더에 의해 만들어졌고 나머지 프로그램이 최신 g ++ 컴파일러로 컴파일 된 경우 왜 이것이 ABI의 MINGW 특정 변경 사항입니까?

 
#include <windows.h> 
#include <stdio.h> 
#include <CkString.h> 
int main(int argc, char *argv[]) { 
    printf("test chilkat\n"); 
    CkString str1; 
    printf("test done\n"); 
} 
 
gdb -i=mi test_chilkat.exe 
Starting program: test_chilkat.exe 
[New Thread 4704.0x1a44] 

Program received signal SIGSEGV, Segmentation fault. 
0x00404442 in CkObject::CkObject()() 
+0

예. http://gcc.gnu.org/gcc-4.7/changes.html을 참조하십시오. 이것은 (특히 std :: list와 std :: pair에서) 라이브러리 전용 변경이라고 생각하며 C++ 11 모드에만 영향을 미칩니다. – dajames

+1

글쎄, GCC 4.7.2는 실제로 GCC 4.6과 ABI 호환성을 회복시킨다. 그래서 OP가 여기에서 겪고있는 것은 아마도 다른 것입니다. –

+2

Linux ABI 호환성 및 Windows ABI 호환성은 완전히 다른 짐승입니다. 일반적으로 모든 종류의 ABI를 유지하기 위해 Windows GCC 릴리스를 고려하지 않습니다. – rubenvb

답변

4

는 MinGW 4.6.2은 확실히 4.7.2보다 CkString 생성자를 호출하는 다른 코드를 생성한다. 여기

내가 ( ./include이 Chilkat 헤더의 위치입니다) 어셈블리 코드 파일에 테스트 프로그램을 컴파일하는 데 사용되는 명령 줄입니다 : 여기

g++ -I ./include -S -masm=intel -std=gnu++0x test.cpp 

printf() 호출에 의해 bookended하게 주석 해체 작업은 (이다 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은 생성자에 "이"포인터를 전달 스택 (Chilkat 라이브러리가 기대하는 것)에서. 4.7.2는 ecx에 "this"포인터를 전달합니다.

4.7.0으로 시작하는 것처럼 보입니다. MinGW는 C++ 클래스 구성원 호출 규칙을 __thiscall으로 변경했습니다.당신은 아마 다른 라이브러리와 함께 자신에게 더 많은 문제를 구입됩니다,

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 

을하지만 : 당신이 나를 위해 테스트 프로그램 작업을하게 -mabi=sysv 옵션을 사용하여 해당 기본값을 대체 할 수 있습니다처럼 보이는 http://mingw-users.1079350.n2.nabble.com/MinGW-GCC-4-7-0-released-td7578133.html

보기 더 복잡한 프로그램 - 예를 들어 최소한 libstdc++.a을 다시 빌드해야합니다.

내가 조금 더는 4.7.x 라이브러리에 대한 Chilkat 개발자를 누를 것 ...

+0

오, 멋진 찾으십시오.그것이 유일한 문제이고 chilkat이 libstdC++ 멤버 함수를 호출하지 않는다고 가정하고 헤더를 수정하여 각 멤버 함수에 대한 호출 규칙에 적절한 '__attribute__'을 명시 적으로 추가하여 해결할 수 있어야합니다. – hvd

+0

Michael, 상세한 조사를하고 2 개의 컴파일러의 어셈블리 출력을 비교하고, 주석을 달고, 해결책이 아닌 경우 (-mabi = sysv) 좋은 대안을 제공 할 시간을내어 주셔서 감사합니다. 정말 감사. 당신이 경고했듯이, 이것은 나의 샘플 테스트 프로그램을 위해 작동하지만, 충돌하는 나의 실제 프로그램을 위해는 작동하지 않는다. 공급 업체로부터 답장을 기다리는 중입니다. –

3

나는 공급 업체 (Chilkat)이야, 그리고 바부에 대한 대답은 "지원되지 않음"있다고 아니었다 그러나 그것은 "아직 지원되지 않는다"는 것이다.

각 Chilkat 릴리스 사이에는 필연적으로 지원이 필요한 새로운 시스템이 있습니다. 이 각각은 (Chilkat에서) 건축 및 유통을위한 자동화 시스템을 생산하는 데 시간이 걸립니다. 새로운 무언가의 출혈 가장자리에 있고, 그것이 Chilkat에 의해 즉시 지원되기를 기대하는 것은 다소 불합리합니다.

현재 Chilkat은 Windows Phone 8, Embarcadero XE3, Mono (Windows, Linux, MAC OS X, iOS, Android 등을위한 크로스 플랫폼), 새로운 Python 3.3.0, MIPS 및 x86 용 Android와 같은 Perl, Python, PHP 등의 버전입니다. Chilkat은 "C"API와 유사한 방식으로 DLL/.so/.dylib 기능 라이브러리를 제공하는 것과 같이 반드시 "새로운"것은 아닌 다른 방법으로 API를 제공하기도합니다.

크로스 플랫폼 API 합리성의 일부로 중요한 내부 개발이 진행되고 있습니다. 예를 들어 "Ck *"C++ 헤더와 구현은 완전히 생성 될 것입니다. 닷넷 어셈블리 관리 헤더와 구현에 대해서도 마찬가지이며, 각각 동일한 내부 구현을 호출합니다. 이것은 두 가지 일을 할 것입니다. (1) 플랫폼 간의 불일치를 제거하고, (2) 외부 레이어를 개선/변경할 수 있습니다. 예를 들어, 각 C++ 클래스 메소드에 호출 규칙 수정자를 추가해야하는 경우. 아마도 "_ stdcall"또는 " _chilkat_call"을 추가 할 수 있습니다. "__chilkat_call"을 한 곳에서 아무 것도 지정하지 않으면 "_ stdcall"또는 " _thiscall"이 도움이됩니다. 이것은 Ck * 헤더와 메소드가 생성 될 때 가능할 것입니다.

요약하면,이 바로 그 순간이 아니라 앞으로 몇 개월 동안 여러분의 필요가 지원 될 것입니다. 죄송 합니다만, 이해해 주시기 바랍니다.