在Windows窗体中使用C ++类导致System.AccessViolationException

时间:2012-07-05 16:58:34

标签: c++ .net winapi runtime-error ifstream

我编写了一些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 ++库和类(我已编写过)和一个托管C ++表单。
  • 到目前为止,我没有遇到任何问题,我已经成功使用了一些C ++库。这是由我最近写的一个新的C ++类引起的。
  • 导致这些违规的C ++类使用std::ifstream读取文件。如果我注释掉std::ifstream input_file(filename);我的Forms项目成功运行。
  • 如果我在一个简单的Win32项目中使用C ++类,它会使用std::ifstream进行编译和运行。
  • 我强烈认为它与this question
  • 有关

有人可以提供任何建议吗?谢谢


编辑:我正在提供我的表单代码的一些部分。 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;
        }
    }
 };

1 个答案:

答案 0 :(得分:0)

这两个陈述似乎相互矛盾:

  

该程序尚未开始运行,而新的,   引起问题的C ++类还没有被构造出来。

     

如果我注释掉新的调用,并且只有一个指向这个新C ++的指针   上课,一切都很好。

问:你能否在你称之为“新”的地方发布代码?或者你称之为“新” - 或许你的意思是“如果我评论出我的新课程”?

问:你能否在构造函数中设置一个断点,查看堆栈跟踪,看看谁在调用它? 何时

========== ADDENDUM ==========

我非常不同意这一说法:

  

这一切都取决于这一行:std :: ifstream input_file(filename);   其中filename是std :: string。

我强烈同意这句话:

  

如果你有静态类成员,你在C#中会得到几乎相同的错误   它们相互依赖,并且不会按照您的顺序进行初始化   期望。在C ++中,如果你有一个静态单例和另一个静态   提到它的成员

调用“ifstream”本身不是问题。相反,以某种方式调用在程序初始化之前调用ifstream的类是问题。

问:你在这堂课上打电话给“新人”吗?如果是的话,在哪里。请剪切/粘贴该代码。

根据MSDN,您应该能够设置“混合模式调试”。我有很多不同的MSVS副本:) ...但是MSVS 2010 / C ++并不是其中之一。请查看此文档: