2017-08-28 5 views
-2

コンパイルされた静的ライブラリ内から外部文字列配列を呼び出すプログラムを作成しています。 の64ビットでプログラムをコンパイルして実行すると問題なく動作します。しかし、* 32ビット*でコードをコンパイルするときに外部配列を呼び出そうとすると、mainを実行するとSegmentation Faultが発生します。ここで外部文字列呼び出しが原因でSegfaultが32ビットで動作し、64ビットで動作する

はコードです:

ヘッダー宣言「hoenyB_lib.h:

#ifndef HONEYB_LIB_H_ 
#define HONEYB_LIB_H_ 

#include <string> 

extern std::string honeyB_libs[]; 

#endif 

エクスターナル定義HoneyB_lib.cpp:

#include <string> 

std::string honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" }; 

エクスターナル使用HoneyB_fcn.cpp:

deque<string> get_array() 
{ 
    deque<string> dst; 
    int i =0; 

    for(;;) 
    { 
     if(honeyB_libs[i] == "") 
      break; 
     else 
     { 
      dst.push_front(honeyB_libs[i]); 
      i++; 
     } 
    } 
    return dst; 
} 

これをコンパイルするMakefileは次のようになります。

all: 
    $(CC) -c -Wall -fPIC source.cpp 
    $(CC) -g -c -fPIC honeyB_fcn.cpp 
    ar rcs libHB.a honeyB_fcn.o 
    g++ -g -c -fPIC honeyB_lib.cpp 
    g++ --whole-archive -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a 
    g++ -L. -o main main.cpp -lHoneyB 

これはmain()が呼び出されても問題なく動作します。しかし、私は、次のと32ビットとしてコンパイルする場合:

all32: 
    $(CC) -m32 -c -Wall -fPIC source.cpp 
    $(CC) -m32 -g -c -fPIC honeyB_fcn.cpp 
    ar rcs libHB.a honeyB_fcn.o 
    g++ -m32 -g -c -fPIC honeyB_lib.cpp 
    g++ --whole-archive -m32 -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a 
    g++ -m32 -L. -o main main.cpp -lHoneyB 

コードは、セグメンテーション違反を与えます。 honeyB_fct.cpphoneyB_libs[]でコールを削除すると、コードがコンパイルされて実行されます。

これがなぜの32ビットで失敗するのか誰も知りませんが、で動作しますか?

ありがとうございます。

+0

'get_array'の呼び出しはどこですか? –

答えて

0

異なる翻訳単位間の初期化の順序は未定義です。グローバル変数HoneyB_lib.cppは、HoneyB_fcn.cppで使用される前に初期化される保証はありません。 64ビットバージョンのために働いた唯一の理由は、あなたが運が良かったからです。

カップルの回避策があります。

  1. はODRを回避するために、匿名の名前空間に包まれhoneyB_lib.hの配列を定義します。ヘッダを含む各TUには、配列の独自のコピーがあります。
  2. また、ヘッダーに配列を定義しますが、配列を返す関数の内部に配置します。コンパイラに最適化する必要があります。そうでない場合は、関数のスコープ内で配列を静的にして参照で返します(つまり、シングルトンにする)。

補助メモとして、ローアレイの代わりにstd::arrayをお勧めします。これにより、get_array関数をちょっときれいにして、""のセンチネル値に頼るのではなく、honeyB_libs.size()(またはさらにはfor (auto&& lib : honeyB_libs) {...})になります。

+1

すべてのグローバル変数は 'main'より前に初期化されていなければなりません。したがって、グローバル変数の初期化ではなく、通常のコードで' get_array'を呼び出す場合は問題ありません。 –

0

ありがとうございました。問題は、文字列のビット数をの32ビットのと比較した場合、の64ビットのとなります。 honeyB_libs []を文字列配列からconst char *配列に変更することで問題が解決しました。これを行う honeyB_lib.h

extern const char* honeyB_libs[]; 

honeyB_lib.cpp

const char* honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" } 

function.cpp

deque<string> get_array() 
{ 
    deque<string> dst; 
    string temp; 
    int i =0; 

    for(;;) 
    { 
    if(strlen(honeyB_libs[i]) == 0) 
     break; 
    else 
    { 
     temp = honeyB_libs[i]; 
     dst.push_front(temp); 
     i++; 
    } 
    } 

    return dst; 
} 

は、私のプログラムが64ビットとしてコンパイルして実行することを可能にする32ビット

関連する問題