4

リリース モードでビルドした後、デバッグ モードでは発生しなかった例外が表示されます。リリース ビルドをデバッグすると、文字列参照が EXE (アプリケーション) から文字列参照を受け取る DLL に正しく渡されていないように見えます。

EXE コードは次のようになります。

string contents = "handle_message(): received=" + msg->encode();
LOG4CXX_DEBUG(logger, contents);

LOG4CXX_DEBUGlog4cxx.dllコードは次のようになります。

CharMessageBuffer& CharMessageBuffer::operator<<(const std::basic_string<char>& msg) {
   if (stream == 0) {
      buf.append(msg);
   } else {
      *stream << msg;
   }
   return *this;
}

デバッガーでコール スタックを見て、ソースのあるフレームに移動すると、それがcontents有効な文字列であることがわかりますsize=583, capacity=838

内側のフレームlog4cxx.dll(スタックの上の次のフレーム) では、文字列参照が表示されます size=838, capacity=363113231(値はすべてガベージです)。

アプリと log4cxx.dll は両方とも、同じランタイム設定 (/MD) を使用して同じマシンでコンパイルされましたが、Visual Studio のバージョンは異なります。log4cxx dll は Visual Studio 2008 を使用してコンパイルされ、アプリケーションは Visual Studio 2010 を使用してコンパイルされました。2 つのオブジェクトで dumpbin を実行すると、次のように表示されます。

私たちのアプリ (EXE)

MSVCP100.dll
MSVCR100.dll

log4cxx.dll (DLL)

MSVCP90.dll
MSVCR90.dll

この問題は、異なるランタイム バージョンを使用していることが原因ですか?

4

2 に答える 2

1

暗黙の疑問は、「できれば文字列やその他の STL コンテナーを使用して、使用している Visual Studio より前または後の別のバージョンの Visual Studio の DLL にデータを渡す方法はありますか?」です。

POD を使用する以外に、おそらく 3 つのアプローチがあります: 共有メモリ、ソケット (ローカル ホストへ)、および MSMQ。これらのメソッドはすべて、さらに大規模なプログラミングを追加する必要がありますが、より深い答えは、インターフェイスが入力パラメーターを変更する方法にあります。

インターネット上で文字列の受け渡しの問題に対する可能な解決策を見つけました。腐敗の層を1つ取り除きます。コンテナーへのポインターを uint にキャストし、uint を渡します。uint をポインターに逆参照すると、オブジェクトが明らかになります。auto_ptrs は通常、このプロセスで削除されるため、使用しないでください。渡されたオブジェクトがまだ正しくオフセットされていない場合 (これは VS08 が VS13 に渡されたときに発生しました)、代わりに文字列の c_str() を渡します。確かに洗練されていませんが、すべての代替案を知る必要があります。コード プロジェクト (2012 年 11 月 22 日) の「方法: DLL から C++ クラスをエクスポートする」を参照してください。

于 2013-12-23T22:56:54.423 に答える