Почему при попытке запустить приложение WinForms, которое использует boost, появляется ошибка «Ошибка отладки». - PullRequest
0 голосов
/ 03 мая 2011

Я работаю в Microsoft Visual Studio 2010 Express.

Я создал новое приложение Windows Forms и добавил одну строку кода (сразу после строки #pragma once в Form1.h):

#include "boost/regex.hpp"

Чтобы компилировать этот проект, я изменяю /clr:pure на /clr.Кроме того, для моей надстройки были заданы пути включения и библиотеки.

Приложение компилируется, но как только я его запускаю, я получаю сообщение об ошибке Debug Assertion Failed.

Ошибка возникает в файле: dgbheap.c в строке: 1516в выражении: _CrtIsValidHeapPointer(pUserData)

Вот полный код для Form1.h, сгенерированного VS:

#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 Forms, но не в консольное приложение?

Спасибо, Уильям

Ответы [ 2 ]

0 голосов
/ 03 мая 2011

Мне понадобится полная трассировка стека (включая модуль и имя функции), чтобы знать наверняка, но я думаю, что вы связались с Boost DLL, которая статически связывала CRT.Это не хорошо, /clr требует использования динамического CRT (MSVCP100.DLL, IIRC).Статически связывая CRT, boost получает свою собственную отдельную кучу, а затем некоторый объект освобождается в кучу, отличную от того, откуда он пришел, вызывая это утверждение.

API-интерфейсы Boost очень тяжелы для объектов и полны встроенных функций, поэтомуЯ не могу себе представить, почему кто-то когда-либо создавал бы Boost DLL, используя статический CRT.Но это обычное объяснение этой неудачи.

0 голосов
/ 03 мая 2011

У вас есть несколько вариантов:

  1. Использовать встроенный класс регулярных выражений * .NET вместо Boost.Regex, поскольку вы уже используете управляемый код
  2. Используйте Boost.Xpressive вместо Boost.Regex;это только заголовок, так что вы не столкнетесь с проблемами конфигурации компилятора / компоновщика, как это происходит со связанными библиотеками
  3. Не только заголовочные библиотеки Boost статически связаны по умолчанию с VC ++;ссылка на Boost.Regex динамически, а не статически.Это описано в Boost.Regex документах следующим образом: " Обратите внимание, что если вы хотите динамически связываться с библиотекой регулярных выражений при использовании динамической среды выполнения C ++, определите BOOST_REGEX_DYN_LINK при сборке проекта."
  4. Если вы хотите продолжить статическое связывание с Boost.Regex, перестройте Boost.Regex с помощью /clr;вы связываете приложение, созданное с /clr, со статической библиотекой, созданной без него - ничего хорошего.Для этого при вызове bjam передайте asynch-exceptions=on и cxxflags="/clr" в качестве аргументов
...