尝试执行使用boost的WinForms应用程序时,为什么会出现Debug Assertion Failed Error?

时间:2011-05-02 23:49:39

标签: .net winforms debugging boost c++-cli

我在Microsoft Visual Studio 2010 Express中工作。

我创建了一个新的Windows窗体应用程序并添加了一行代码(紧接在Form1.h中的#pragma once行之后):

#include "boost/regex.hpp"

要将此项目编译,我将/clr:pure更改为/clr。此外,include和library路径设置为我的boost版本。

应用程序编译,但是一旦运行它我就会收到Debug Assertion Failed错误。

  

错误发生在File:dgbheap.c的第1516行   
在表达式:_CrtIsValidHeapPointer(pUserData)

以下是VS生成的Form1.h的完整代码:

#pragma once

#include "boost/regex.hpp"

namespace plz {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// Summary for Form1
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }

    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->SuspendLayout();
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(292, 273);
            this->Name = L"Form1";
            this->Text = L"Form1";
            this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
            this->ResumeLayout(false);

        }
#pragma endregion
    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
             }
    };
}

我理解断言失败时会发生断言失败错误,但是导致这种情况的原因是什么?当我将它放在Windows窗体应用程序中而不是在控制台应用程序中时,为什么这包括失败?

谢谢你, 威廉

2 个答案:

答案 0 :(得分:0)

您有几个选择:

  1. 使用.NET's built-in regex class而非Boost.Regex,因为您已使用托管代码
  2. 使用Boost.Xpressive而不是Boost.Regex;它只是标题,因此您不会像使用链接库那样遇到编译器/链接器配置问题
  3. 默认情况下,非标头的Boost库与VC ++静态链接;动态链接到Boost.Regex而不是静态链接。这在Boost.Regex docs中有所描述:“请注意,如果要在使用动态C ++运行时动态链接到正则表达式库,请在构建项目时定义BOOST_REGEX_DYN_LINK
  4. 如果要继续静态链接到Boost.Regex,请使用/clr重建Boost.Regex;您将使用/clr构建的应用程序链接到没有它构建的静态库 - 没有好处。为此,在调用bjam时,将asynch-exceptions=oncxxflags="/clr"作为参数传递

答案 1 :(得分:0)

我需要一个完整的堆栈跟踪(包括模块和函数名称)以确定,但我认为你已经链接了一个静态链接CRT的Boost DLL。这不好,/clr需要使用动态CRT(MSVCP100.DLL,IIRC)。通过静态链接CRT,boost获得自己独立的堆,然后将一些对象释放到不同于它触发此断言的堆中。

Boost的API非常庞大,内置函数,所以我无法想象为什么有人会使用静态CRT构建Boost DLL。但这是对这次失败的通常解释。