0

さまざまな C++ ライブラリを使用するいくつかの C++ クラスを作成しました。Windows フォーム プロジェクトを作成し、クラスを正常に使用できるように設定しました。ただし、最近別の C++ クラスを作成したところ、一貫して次のようになります。

A first chance exception of type 'System.AccessViolationException' occurred in TEST_OCU.exe

これは次のことにつながります。

 An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module.
 Additional information: The type initializer for '<Module>' threw an exception.

プログラムはまだ実行を開始しておらず、問題の原因となっている新しい C++ クラスはまだ作成されていません。呼び出しをコメント アウトし、newこの新しい C++ クラスへのポインターしかない場合は、すべて正常にコンパイルされます。しかし、どこかで次のようなことをすると:

 if(new_class_ptr != NULL)
    new_class_ptr->SomeFunction()  //It doesn't matter what function this is

これにより、これらの違反が再びスローされます


いくつかの事実:

  • コンパイルとリンクは問題ありません。これは実行時の問題のようです。
  • 私のソリューションでは、(私が作成した) アンマネージ C++ ライブラリとクラス、および 1 つのマネージ C++ フォームを使用しています。
  • これまでのところ、問題は発生していません。しばらくの間、いくつかの C++ ライブラリを正常に使用してきました。これは、私が最近書いた新しい C++ クラスが原因です。
  • これらの違反を引き起こす C++ クラスstd::ifstreamは、ファイルを読み込むために使用します。コメントアウトするとstd::ifstream input_file(filename);、Forms プロジェクトは正常に実行されます。
  • 単純な Win32 プロジェクトで C++ クラスを使用すると、std::ifstream.
  • 私はそれがこの質問に関連していると強く感じています

誰でもアドバイスを提供できますか?ありがとうございました


編集:私が持っているフォームコードの一部を提供しています。RTSPConnection は正常に動作し、問題のあるクラスは RTPStream です

public ref class Form1 : public System::Windows::Forms::Form
{
public:
  // ... Lots of generated code here ...

//Calls I've written
    private: static RTSPConnection * rtsp_connection_ = NULL; //This class works
    private: static RTPStream * rtp_connection_ = NULL; //This class does not
    bool streaming_;
    System::Threading::Thread^ streaming_thread_;

    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
        if(rtsp_connection_ == NULL)
        {
            rtsp_connection_ = new RTSPConnection("rtsp://192.168.40.131:8554/smpte");
            streaming_ = false;
        }

            //if(rtp_connection_ == NULL)
            //   rtp_connection_ = new RTPStream("test");

    }

    private: System::Void Form1_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
        if(rtsp_connection_ != NULL)
            rtsp_connection_->StopStreaming();
    }

    private: System::Void button1_MouseClick(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
        if(!streaming_)
        {
            //Start Streaming
            streaming_thread_ = gcnew Thread(gcnew ThreadStart(&Form1::WorkerThreadFunc));
            streaming_thread_->Start();

            this->button1->Text = L"Stop Streaming";
            streaming_ = true;
        }
        else
        {
            //Stop Streaming
            if(rtsp_connection_ != NULL)
            rtsp_connection_->StopStreaming();

            //THIS CALL RIGHT HERE WILL THROW AN ACCESS VIOLATION
            if(rtp_connection_ != NULL)
                rtp_connection_->StopStreaming();
            this->button1->Text = L"Start Streaming";
             streaming_ = false;
        }
    }
 };
4

1 に答える 1

0

これらの 2 つのステートメントは互いに矛盾しているように見えます。

プログラムはまだ実行を開始しておらず、問題の原因となっている新しい C++ クラスはまだ作成されていません。

新しい呼び出しをコメント アウトし、この新しい C++ クラスへのポインターしかない場合、すべてが正常にコンパイルされます。

Q: 「新規」と呼んでいるコードを投稿していただけますか? それとも、「新しい」と呼んでいますか? おそらく、「新しいクラスをコメントアウトした場合」という意味でしたか?

Q: コンストラクターにブレークポイントを設定し、スタック トレースを見て、誰がそれを呼び出しているかを確認していただけますか? そしていつ

========== 補遺 ==========

私はこの声明に強く同意しません:

それはすべて次の行にかかっています: std::ifstream input_file(filename); filename は std::string です。

私はこの声明に強く同意します:

相互に依存する静的クラス メンバーがあり、期待する順序で初期化されていない場合、C# でほぼ同じエラーが発生します。C++ で、静的シングルトンとそれを参照する別の静的メンバーがある場合

「ifstream」を呼び出すこと自体は問題ではありません。むしろ、プログラムが初期化される前に ifstream を呼び出すクラスを何らかの方法で呼び出すこと問題です。

Q: このクラスで「新規」と呼んでいますか? もしそうなら、どこで。そのコードを切り取って貼り付けてください。

MSDN によると、「混合モードのデバッグ」を設定できるはずです。私は MSVS のさまざまなコピーをたくさん持っています :) ... しかし、MSVS 2010/C++ はそれらの 1 つではありません。このドキュメントを見てください:

于 2012-07-05T17:49:37.733 に答える