2

Windows では、g++ 4.6 (mingw) および -std=c++0x を使用し、サード パーティの静的ライブラリ (mingw で使用するためにベンダーから提供されたもの) とリンクすると、アプリケーションは正常に動作します。-std=c++11 を使用できるように g++ 4.7.2 (mingw) に切り替えたところ、アプリケーションは正常にビルドされますが、実行時にクラッシュします。ベンダー提供のライブラリへの呼び出しをコメントアウトすると、クラッシュしません。ライブラリ ベンダーのカスタマー サポートに問い合わせたところ、これはサポートされていないと言われました。

私の質問は、新しいバージョンの g++ コンパイラに移行するときに「ABI の非互換性はありますか?」ということです。後方互換性はないのですか?コンパイラの新しいバージョンは、既存および従来のサードパーティの静的ライブラリで動作するはずではありませんか?

これは Windows (mingw) プラットフォームでのみ発生することに注意してください。Linux で問題なく動作します。

これに関する詳細情報を追加しました:

ソースが -std=c++11 コンパイル オプションを指定して g++ 4.7.2 でコンパイルされた Windows アプリケーションで Chilkat の MinGW C++ (静的) ライブラリを使用した人はいますか? Chilkat api にアクセスするとアプリがクラッシュします (たとえば、CkString オブジェクトがインスタンス化された場合)。g++ 4.6.2 (std=c++0x を使用) で正常に動作します。g++ 4.7.2 を搭載した Linux では、このプログラムは正常に動作します。4.6.2 から 4.7.2 に移行するときに ABI の非互換性がある場合、Linux でも動作しないはずですよね? プログラムの残りの部分が最新の g++ コンパイラでコンパイルされている場合、MINGW で使用するためにベンダーによって作成されたスタティック ライブラリ chilkat-9.3.2/lib/libchilkat.a がなぜ使用されるのでしょうか --- これは ABI の MINGW 固有の変更ですか?

#include <windows.h>
#include <stdio.h>
#include <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、セグメンテーション違反。
CkObject::CkObject() () の 0x00404442
4

2 に答える 2

4

CkStringMinGW 4.6.2は、コンストラクターを呼び出すために4.7.2とは異なるコードを確実に生成しています。

./includeテストプログラムをアセンブリコードファイル( Chilkatヘッダーの場所)にコンパイルするために使用したコマンドラインは次のとおりです。

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

printf()これは、2つの呼び出し(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++クラスメンバーの呼び出し規約をに変更しました__thiscallhttp://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ライブラリをもう少し押してもらいたいと思います...

于 2012-10-30T07:59:15.313 に答える
3

私はベンダー (Chilkat) です。Babu への回答は、「サポートされていない」ではなく、「まだサポートされていない」というものでした。

各 Chilkat リリースの間に、サポートを必要とする新しいシステムが必然的に存在します。これらはそれぞれ、ビルドと配布用の自動化されたシステムを作成するのに (Chilkat で) 時間がかかります。新しい何かの最先端にいて、それがすぐに Chilkat によってサポートされることを期待するのは、やや不合理です。

現在、Chilkat は次の新しいシステムのサポートを計画しています: Windows Phone 8、Embarcadero XE3、Mono (Windows、Linux、MAC OS X、iOS、Android などのクロスプラットフォーム)、Perl の新しいバージョン、 Python 3.3.0、Android for MIPS および x86 などの Python、PHP など。Chilkat はまた、「C」API と同様の方法で DLL/.so/.dylib 関数 lib を提供するなど、必ずしも「新しい」とは限らない他の方法で API を提供する予定です。

クロスプラットフォーム API の合理性の一環として、重要な内部開発が進行中です。たとえば、「Ck*」C++ ヘッダーと実装は完全に生成されます。同じことが .NET アセンブリ マネージ ヘッダーと実装にも当てはまり、それぞれが同じ内部実装を呼び出します。これにより、(1) プラットフォーム間の不一致が解決され、(2) 外部レイヤーの改善/変更が可能になります。たとえば、各 C++ クラス メソッドに呼び出し規約修飾子を追加する必要がある場合です。おそらく、"_ stdcall" または " _chilkat_call" を追加して、"__chilkat_call" を 1 か所で何も定義しないか、"_ stdcall" または "_thiscall" が役立ちます。これは、Ck* ヘッダーとメソッドが生成されたときに可能になります。

要約すると、あなたの必要性は、今すぐではなく、今後数か月でサポートされるでしょう。申し訳ありませんが、ご理解いただければ幸いです。

于 2012-11-01T14:54:48.720 に答える