Вызов IOS :: exception (...) заставляет EOF генерировать InteropServices.SEHException из std :: getline (...) в C ++ - CLI, почему? - PullRequest
0 голосов
/ 22 ноября 2011

Я запускаю следующую функцию для загрузки файла. Он переносится из CLI в стандартный C ++ и демонстрирует неожиданное поведение, когда я пытаюсь указать, что я хотел бы выбросить все исключения, кроме EOF.

bool parseFile(ManagedClass *%parsedFileAsManagedObject, const string &fileName);
    std::string line;
    bool success = true;
    ifstream is(fileName.c_str());
    //Unless I comment out the following line I get problems
    is.exceptions( ifstream::badbit | ifstream::failbit );
    //do stuff
    try {
        while (getline(is, line)) {
        //do stuff again
            parsedFileAsManagedObject = gcnew ManagedClass(12, 44);
        }
    } catch (Exception ^ex) {
        log(ex->ToString() + ex->StackTrace + ex->InnerException);
        success = false;
        //Hit debugger here.
    }
    return success;
}

При запуске, как указано выше, я получаю:

Внешний компонент выдал исключение.

при _CxxThrowException(Void* , _s__ThrowInfo* )

в std.ios_base.clear(ios_base* , Int32 _State, Boolean _Reraise) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ xiosbase: строка 294

в std.basic_ios<char,std::char_traits<char> >.clear(basic_ios<char\,std::char_traits<char> >* , Int32 _State, Boolean _Reraise) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ ios: строка 44

в std.basic_ios<char,std::char_traits<char> >.setstate(basic_ios<char\,std::char_traits<char> >* , Int32 _State, Boolean _Reraise) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ ios: строка 55

в std.basic_istream<char,std::char_traits<char> >._Ipfx(basic_istream<char\,std::char_traits<char> >* , Boolean _Noskip) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ istream: строка 120

в std.basic_istream<char,std::char_traits<char> >.sentry.{ctor}(sentry* , basic_istream<char\,std::char_traits<char> >* _Istr, Boolean _Noskip) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ istream: строка 76

в std.getline<char,struct std::char_traits<char>,class std::allocator<char> >(basic_istream<char\,std::char_traits<char> >* _Istr, basic_string<char\,std::char_traits<char>\,std::allocator<char> >* _Str, SByte _Delim) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ string: строка 483

в std.getline<char,struct std::char_traits<char>,class std::allocator<char> >(basic_istream<char\,std::char_traits<char> >* _Istr, basic_string<char\,std::char_traits<char>\,std::allocator<char> >* _Str) в c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ string: строка 531

в myprojrepeated.LevelParser.parseFile(ManagedClass *%parsedFileAsManagedObject, basic_string<char\,std::char_traits<char>\,std::allocator<char> >* fileName) в c: \ Documents and Settings \ KingKewlio \ Мои документы \ Visual Studio 2008 \ projects \ myproj \ myprojrepeated \ levelparser.cpp: строка 355

описание моего исключения.

Когда я комментирую эту строку, все хорошо на земле Интеропа.

Кто-нибудь может объяснить, почему Interop это не нравится?

Я приписываю Interop, потому что когда я не удосужился окружить эти getline(...) в try и catch, я получаю следующую ошибку

System.Runtime.InteropServices.SEHException

сообщается из верхней части стека вызовов, показанного выше и снова ниже:

[Управляемый в собственный переход]

myproj.exe!std::ios_base::clear(int _State = 3, bool _Reraise = false) Строка 294 + 0x3a байт C ++

myproj.exe!std::basic_ios<char,std::char_traits<char> >::clear(int _State = 3, bool _Reraise = false) Строка 45 C ++

myproj.exe!std::basic_ios<char,std::char_traits<char> >::setstate(int _State = 2, bool _Reraise = false) Строка 56 C ++

myproj.exe!std::basic_istream<char,std::char_traits<char> >::_Ipfx(bool _Noskip = true) Строка 121 C ++

myproj.exe!std::basic_istream<char,std::char_traits<char> >::sentry::sentry(std::basic_istream<char,std::char_traits<char> >& _Istr = {...}, bool _Noskip = true) Строка 76 + 0x18 байт C ++

myproj.exe!std::getline<char,std::char_traits<char>,std::allocator<char> >(std::basic_istream<char,std::char_traits<char> >& _Istr = {...}, std::basic_string<char,std::char_traits<char>,std::allocator<char> >& _Str = {...}, char _Delim = 10 ' ') Строка 483 + 0xe байтов C ++

myproj.exe!std::getline<char,std::char_traits<char>,std::allocator<char> >(std::basic_istream<char,std::char_traits<char> >& _Istr = {...}, std::basic_string<char,std::char_traits<char>,std::allocator<char> >& _Str = {...}) Строка 531 + 0x33 байта C ++

Ответ https://stackoverflow.com/q/8144268/866333 на мой предыдущий вопрос указывает на то, что это неожиданное поведение, но я готов оказаться неправым.

1 Ответ

2 голосов
/ 22 ноября 2011

Может показаться, что std::ios_base создает исключение.Поскольку она является частью стандартной библиотеки C ++, исключение, вероятно, составляет std::exception &.Не Exception ^.Поскольку ваш код не перехватывает std::exception &, он, вероятно, собирается завершиться.Это можно подтвердить, добавив

catch (...) {
    log("Unknown exception thrown!");
    throw;  //rethrow it.  ALWAYS RETHROW UNKNOWN EXCEPTIONS.  PERIOD.
}

. Кроме того, getline(is, line) установит оба значения EOF и failbit, , если файл заканчивается напустая строка.

...