使用C++;Windows窗体中的类导致System.AccessViolationException 我已经编写了一些C++类,它们使用各种C++库。我制作了一个Windows窗体项目,并将其设置为成功使用我的类。但是,我最近又做了一个C++类,现在我总是得到:

使用C++;Windows窗体中的类导致System.AccessViolationException 我已经编写了一些C++类,它们使用各种C++库。我制作了一个Windows窗体项目,并将其设置为成功使用我的类。但是,我最近又做了一个C++类,现在我总是得到:,c++,.net,winapi,runtime-error,ifstream,C++,.net,Winapi,Runtime Error,Ifstream,在TEST_OCU.exe中发生了类型为“System.AccessViolationException”的第一次意外异常 这导致: An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module. Additional information: The type initializer for '<Module>' threw an exception.

在TEST_OCU.exe中发生了类型为“System.AccessViolationException”的第一次意外异常

这导致:

 An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module.
 Additional information: The type initializer for '<Module>' threw an exception.
这将再次抛出这些违规行为


一些事实:

  • 编译和链接很好,这似乎是一个运行时问题
  • 我的解决方案使用了非托管C++库和类(我已经编写),还有一个管理C++表单。 到目前为止,我还没有遇到任何问题,我已经成功地使用了一些C++库。这是由我最近写的一个新C++类引起的。
  • 导致这些违规的C++类使用了代码> STD::IFStuts在文件中读取。如果我注释掉
    std::ifstream输入文件(文件名)我的表单项目成功运行
  • 如果我在一个简单的Win32项目中使用C++类,它编译并运行得很好,用<代码> STD::IFSWATE .
  • 我有一种强烈的感觉,它与
有人能提供一些建议吗?多谢各位


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

这两种说法似乎相互矛盾:

程序还没有开始运行,新的, 导致C++类的问题还没有被构建。

如果我注释了新的调用,并且只有一个指向这个新C++的指针 同学们,一切都很好

问:你能把代码贴在你叫“新”的地方吗?或者你是说“新”——也许你的意思是“如果我把我的新课注释掉”

问:您能在构造函数中设置一个断点,查看堆栈跟踪,看看是谁在调用它吗?什么时候

===============附录===================

我强烈反对这种说法:

这一切都取决于这一行:std::ifstream输入文件(filename); 其中filename是一个std::字符串

我非常同意这一说法:


如果有静态类成员,在C#中会出现几乎相同的错误 这是相互依赖的,它们不是按照您的顺序初始化的 期待。在C++中,如果你有一个静态的单体和另一个静态的 提到它的成员

调用“ifstream”本身并不是问题。相反,问题在于如何在程序初始化之前调用调用ifstream的类

问:你在这门课上叫“新”吗?如果有,在哪里。请剪切/粘贴那个代码

根据MSDN,您应该能够设置“混合模式调试”。我有很多不同的MSV副本:)。。。但是MSVS2010/C++并不是其中之一。请参阅以下文档:


您需要调试它。项目+属性,调试选项卡,勾选“启用非托管代码调试”选项。调试+异常,勾选Win32异常的抛出框。由于找不到这个,我使用的是VS2010。将调试器类型设置为“Mixed”。如果您有相互依赖的静态类成员,并且它们没有按照您期望的顺序初始化,则在C#中会出现几乎相同的错误。在C++中,如果有一个静态的单体和另一个静态成员,则如果在初始化之前初始化了该成员,则初始化该模块时会得到此错误。你的类或源文件有任何静态数据吗?嗨,我有。突破点永远不会达到。仅仅在代码中包含构造函数就会导致问题,即使它从未到达。注释掉构造函数,将我的ptr设置为NULL并执行
if(ptr!=NULL)ptr->SomeFunction()
会引发相同的错误。问:您是否在MSVS IDE中明确“启用非托管调试”?问:您使用的是MSVS2010Pro(或更高版本)还是MSVS2010Express?您使用的是C++/CLI(托管代码)还是非托管代码?Hans Passant也建议这样做,但是,我在项目属性页中找不到该选项。我使用的是托管代码,但它使用的是我编写的非托管C++库。如果我使用
std::ifstream
@Constantin-我添加了一些新的信息,那么这些工作中的大部分都不会出现。请不要关注“std::ifstream”。。。可能的例外是,您可能正在调用16位Unicode版本的ifstream,但代码需要8位ASCII版本(反之亦然)。但是我认为你最好花时间1)让调试器工作,2)找到静态对象实例,我很确定你正在创建(过早创建!)IMHO。。。请发布更多的代码,它甚至可以远程应用…Paul,我让调试器工作了,遗憾的是,我使用的第三方C++库没有附带调试编译的库。因此,调用第三方库的我的库也被编译为“Release”。保罗,我想你们已经掌握了8位ASCII码和16位ASCII码。主要是因为我从应用程序中删除了所有构造函数调用。我将修改上面的代码以显示。
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;
        }
    }
 };