私は現在、私のdllと私の実際のプロジェクトで異なるCRT設定(MTd MDd)によってヒープの破損が発生しました。 私が奇妙なことに気づいたのは、DLL内のデストラクタを仮想に設定したときにアプリケーションがクラッシュしただけだということです。 簡単な説明はありますか?私はヒープ上にないメモリを解放することはできませんが、デストラクタを非仮想として定義すると、どこが違うのでしょうか。CRT仮想デストラクタ
いくつかのコードだけで、それは少し明確にする
DLL
#pragma once
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {};
_declspec(dllexport) virtual ~CTestClass() {};
};
そして、私のプロジェクト
int main(int argc, char* argv[])
{
CTestClass *foo = new CTestClass;
delete foo; // Crashes if the destructor is virtual but works if it's not
}
また、declspecを* class *( 'class _declspec(dllexport)CTestClass {...}')に移動してメンバーごとのdeclspecを削除することで同じ問題がありますか?ちょっと興味があるんだけど。そして、呼び出しコードとDLLは、同じCRT(デバッグまたはリリース)を使用している必要があるので、考慮すべき点があることに注意してください。私は混合モードがサポートされているかどうかも分かりません(私はそれがそうではないと思います)。 – WhozCraig
プロセス内に複数のCRTのコピーがあります。そして、クラス・メソッドだけをエクスポートし、vテーブルはエクスポートしません。これがどのように相互作用してコードを爆破するのかを推測しようとするのは、それほど生産的ではないと予想されます。仮想メソッドを使用してクラスをエクスポートするには、クラス全体をエクスポートする必要があります。* class *キーワードの隣に__declspec(dllexport)を配置します。オブジェクトを作成して破棄するには、単一のアロケータを使用する必要があります。あなたが/ MDを一貫して構築し、まったく同じコンパイラバージョンを使用しない限り、保証するのは非常に難しいです。モジュールの境界を越えてC++クラスを公開するのは危険です。 –
あなたは正しいとはいえ、それがうまくいかない理由がわかっても、あまり助けにならないでしょう。とにかくあなたの考えのためにとにかく:) – Poisonbox