Calling IOS::exception(…) causes EOF to throw InteropServices.SEHException from std::getline(…) in C++-CLI, why?

廉价感情. 提交于 2019-12-25 03:55:30

问题


I run the following function to load a file. It is being ported from CLI to standard C++ and exhibits unexpected behaviour when I attempt to specify that I would like to throw all exceptions except 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;
}

When run as above I get:

External component has thrown an exception.

at _CxxThrowException(Void* , _s__ThrowInfo* )

at std.ios_base.clear(ios_base* , Int32 _State, Boolean _Reraise) in c:\program files\microsoft visual studio 9.0\vc\include\xiosbase:line 294

at std.basic_ios<char,std::char_traits<char> >.clear(basic_ios<char\,std::char_traits<char> >* , Int32 _State, Boolean _Reraise) in c:\program files\microsoft visual studio 9.0\vc\include\ios:line 44

at std.basic_ios<char,std::char_traits<char> >.setstate(basic_ios<char\,std::char_traits<char> >* , Int32 _State, Boolean _Reraise) in c:\program files\microsoft visual studio 9.0\vc\include\ios:line 55

at std.basic_istream<char,std::char_traits<char> >._Ipfx(basic_istream<char\,std::char_traits<char> >* , Boolean _Noskip) in c:\program files\microsoft visual studio 9.0\vc\include\istream:line 120

at std.basic_istream<char,std::char_traits<char> >.sentry.{ctor}(sentry* , basic_istream<char\,std::char_traits<char> >* _Istr, Boolean _Noskip) in c:\program files\microsoft visual studio 9.0\vc\include\istream:line 76

at 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) in c:\program files\microsoft visual studio 9.0\vc\include\string:line 483

at 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) in c:\program files\microsoft visual studio 9.0\vc\include\string:line 531

at myprojrepeated.LevelParser.parseFile(ManagedClass *%parsedFileAsManagedObject, basic_string<char\,std::char_traits<char>\,std::allocator<char> >* fileName) in c:\documents and settings\KingKewlio\my documents\visual studio 2008\projects\myproj\myprojrepeated\levelparser.cpp:line 355

describing my exception.

When I comment out that line all is well in the land of Interop.

Can anybody explain why Interop doesn't like it?

I attribute Interop because when I don't bother to surround that getline(...) in try and catch I get the following error

System.Runtime.InteropServices.SEHException

reported from the top of the call stack shown above and again below:

[Managed to Native Transition]

myproj.exe!std::ios_base::clear(int _State = 3, bool _Reraise = false) Line 294 + 0x3a bytes C++

myproj.exe!std::basic_ios<char,std::char_traits<char> >::clear(int _State = 3, bool _Reraise = false) Line 45 C++

myproj.exe!std::basic_ios<char,std::char_traits<char> >::setstate(int _State = 2, bool _Reraise = false) Line 56 C++

myproj.exe!std::basic_istream<char,std::char_traits<char> >::_Ipfx(bool _Noskip = true) Line 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) Line 76 + 0x18 bytes 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 ' ') Line 483 + 0xe bytes 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 = {...}) Line 531 + 0x33 bytes C++

An answer https://stackoverflow.com/q/8144268/866333 to my previous question indicates that this is unexpected behaviour but I am prepared to be proved wrong.


回答1:


It would appear as if std::ios_base is throwing an exception. Since it is part of the C++ standard library, the exception is probably a std::exception &. Not a Exception ^. Since your code doesn't catch std::exception &, it is probably about to terminate. This can be confirmed by adding a

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

Also, getline(is, line) will set both EOF and failbit both, if the file ends in an empty line.



来源:https://stackoverflow.com/questions/8227212/calling-iosexception-causes-eof-to-throw-interopservices-sehexception-fro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!