リリースモードのEXEでデバッグモードのDLLを実行することはできますか?
このシナリオを試していますが、EXE はデバッグ DLL をロードせず、「このアプリケーションは開始できませんでした...」というエラーをスローします。
これは良いシナリオではないことはわかっていますが、特定の要件のために、これを機能させる必要があります。
dll インターフェイスが、デバッグとリリースで異なるように見える可能性のあるクラスに依存していない場合に機能します。たとえば、MSVC の std::string と std::vector は、デバッグとリリースで互換性がありません。(フェンス...)
たとえば
std::string GetName();
動作しないでしょう。
さらに、debug/release は異なるランタイムを使用するため、new と delete はシフトしないでください。とにかく、常にdelete
同じコンテキスト (dll/exe) にある必要がありますnew
。
はい、これは機能します。
「アプリケーションを起動できませんでした」という問題は、DLLのデバッグビルド(Visual Studioを使用してマシン上にビルドされたもの)を、DEBUGCRTがインストールされていないマシンにコピーした可能性があります。通常、MSVCRTD(version).dllをプログラムファイルと同じディレクトリにコピーすると、この問題が解決します。私はここでこれのいくつかをカバーする以前の答えを持っています。
最善の策は、すべてのバイナリを常に同じダイナミックMSVCRT DLLにリンクして、すべてが同じランタイムを共有するようにすることです。
もう1つの簡単な回避策は、同じフレーバーのMSVCRT DLLを使用するように(またはCRTに静的にリンクするように)DEBUGDLLをコンパイルすることです。VSプロジェクトのプロパティページ(コード生成だと思います)のどこかに、CRTを選択するためのドロップダウンがあります。リテールMSVCRTをデバッグDLLにリンクすること、または静的にリンクすることには何の問題もありません。
注意すべき点は、異なるバイナリにリンクされたデバッグCランタイムの異なるフレーバーがある場合です。EXE用にリリースMSVCRTdllがリンクされているが、DLL用にMSCVRTD DLLをデバッグしている場合、いくつかの状況で問題が発生する可能性があります。これは、ハンドルとメモリブロックがCRTの2つの異なるインスタンスによって追跡されるためです。
例:
EXEでメモリを割り当てたが、DLLで解放した場合。およびその逆。
EXEではfopen()で開かれたが、EXEでは使用または閉じられたファイルハンドル(およびその逆)。
DLLのインターフェイスのヘッダーファイルの場合、ヘッダーファイルに任意の種類のインライン関数またはメソッドを実装することは、#1または#2を発生させる簡単な方法です。
STLオブジェクト(std :: string、std :: list、std :: vector)を共有することは、混合CRTの使用には絶対にノーノーです。