2011-12-06 9 views
0

Iは、DLLまたは共有オブジェクトが、オブジェクトのforeignObject生成MYDLL:インターフェイスでdll/soを介して注入されたクラスで例外を使用するのは安全ですか?

class ForeignObject : public LocalInterface { 
    virtual void some_func(Injector& i) { 
    i.inject(); 
    } 
}; 

は、このようになります。

class Injector { 
    virtual void inject() = 0; 
}; 

class LocalInterface { 
    virtual void some_func(Injector& i) = 0; 
}; 

その後、私は次のようにします。が、それはこのような例外をスローする安全/安全ではないである理由

class MyInjector : public Injector { 
    virtual void inject() {throw std::runtime_error("arrgghh");} 
}; 

int main() { 
    LocalInterface* foreign_obj = create_object_from_my_dll(); 
    MyInjector injector; 
    foreign_obj->some_func(injector); 
    destroy_object_from_my_dll(foreign_obj); 
    return 0; 
} 

私の質問は、です。同じコンパイラでビルドすると安全ですか?コンパイラ間?

答えて

1

私は答えがOSによって異なると言います。しかし私が扱ってきたすべてのユニセフ(LinuxやMac OS Xを含む)にとって、それは安全です。もちろん、同じABIを使ってコンパイラをコンパイルする必要がありますが、g ++のABIは数年で変化していません(正確には覚えていませんが、最後の大きな変更は3.2だと思います)。また、Linuxで使用されるモデルでは、リンケージはコードの動作に影響を与えません。したがって、コードを動的にリンクされたファイル(つまり共有オブジェクトファイル)に安全に置くことができ、静的にリンクされているかのように動作します。

Windowsでは、VC++を使用すると、別のコンパイラでライブラリをコンパイルできなくなります。プログラムとライブラリは同じバージョンのVC++を使用する必要がありますが、いずれの方向にも互換性はありません。 g ++を使用している場合は、g ++の別のバージョン(UNIXの場合など)でコンパイルできますが、VC++ではコンパイルできません。それは危険です、私はDLLとして奇妙な動作を持っているWindowsの専門家の答えを聞かせて、私はオブジェクトが常にそれをロードしたDLLの範囲内で破壊する必要があります覚えているが、私は100%確かに。

+0

あなたはOSに依存していると言いますが、Linuxのすべてのコンパイラは同じABI(g ++ <3.2を除く)に従っていますか? – daramarak

+0

gccとclangの両方が標準ABIであるItanium C++ ABI(cf. http://sourcery.mentor.com/public/cxx-abi/abi.html参照)を使用しているようです。したがって、C++コンパイラがこのABIを使用しているかどうか、またはそれを使用するように構成できるかどうかを確認する必要があります。しかし、存在する唯一のABIではないので、すべてのC++コンパイラがLinux上で同じABIを使用するかどうかを確認することはできません。 – PierreBdR

+0

@daramarakたとえば、clangはgccと同じItanium ABIを使用しています。したがって、問題なくコードをコンパイルすることができます。 – PierreBdR

0

同じコンパイラ(同じランタイムlib)でビルドしても、実行時のlibが異なる場合は、プログラムでメモリ破損が発生してクラッシュすることは安全です。一般的に例外はありませんが、dllからエクスポートされるクラスを持つ特別な問題はありません。例外がエクスポートされ、これが問題になります。

+0

例外を作成するクラスは、dll/soに注入されてエクスポートされません。 – daramarak

+0

私はあなたの場合、例外クラスstd :: runtime_errorを意味します。 – AlexTheo

+0

あなたは、プログラムのメインで作成された関数は、DLLのランタイムライブラリで実行されていると言っていますか?私が理解しているように、ランタイムエラーの構築は、すでにメインプログラムでコンパイルされています。コピー制作などの場合もそうです。 – daramarak

関連する問題