7

C++ クラス コンストラクターは、インライン化することも、インライン化しないこともできます。しかし、インライン クラス コンストラクターのみが Visual Studio のメモリ クラッシュを回避できるという奇妙な状況を発見しました。例は次のとおりです。

dll.h

class _declspec(dllexport) Image 
{
    public:
        Image();
        virtual ~Image();
};

class _declspec(dllexport) Testimage:public Image 
{
public:
    Testimage();

    virtual ~Testimage();
};

typedef std::auto_ptr<Testimage> TestimagePtr;

dll.cpp

#include "dll.h"
#include <assert.h>


Image::~Image()
{
            std::cout<<"Image is being deleted."<<std::endl;
}
Image::Image()
{
}

Testimage::Testimage()
{

}

Testimage::~Testimage()
{
        std::cout<<"Geoimage is being deleted."<<std::endl;
}

dll ライブラリは動的ライブラリとしてコンパイルされ、C++ ランタイム ライブラリに静的にリンクされます ( Multi-threaded Debug (/MTd))。ライブラリを実行する実行可能プログラムは次のとおりです。

int main()
{
    TestimagePtr my_img(new Testimage());
    return 0;
}

実行可能プログラムは dll ライブラリを呼び出し、ランタイム ライブラリにも静的にリンクします。私が抱えている問題は、実行可能プログラムを実行すると、次のエラー メッセージが表示されることです。 ここに画像の説明を入力

ただし、次のコードが示すように、dll のクラス コンストラクターがインライン化されている場合:

class _declspec(dllexport) Image 
{
    public:
        Image();
        virtual ~Image();
};

class _declspec(dllexport) Testimage:public Image 
{
public:
    Testimage()
    {
    }

    virtual ~Testimage();
};

クラッシュは消えます。誰かが背後にある理由を説明できますか? ありがとう!ちなみに私はVC2010を使っています。

編集:次の状況でも同じクラッシュが発生します。

状況 1

int main()
{
    //TestimagePtr my_img(new Testimage());
    Testimage *p_img;
    p_img = new Testimage();
    delete p_img;
    return 0;
}
4

2 に答える 2

3

VC2010 で問題を再現しようとしましたが、クラッシュしません。コンストラクターをインラインで使用するかどうかに関係なく動作します。あなたの問題はおそらくあなたがここに書いていることではありません。

おそらく CMake で生成されたために、ファイル パスを絶対パスに設定する必要があるため、プロジェクトを開くのが難しすぎます。(そのため、ファイルはコンパイラによって検出されません)。

あなたのコードに見られる問題は、エクスポートされたクラスを _declspec(dllexport) で直接宣言していることです。

これを行うには #Define が必要であり、exe コンパイルから読み取ったときの値は _declspec(dllimport) である必要があります。問題はそこから来ているのかもしれません。

于 2013-05-29T13:52:45.027 に答える