मैं एक बड़ी अप्रबंधित सी ++ लाइब्रेरी और एक बड़ी सी # लाइब्रेरी पर एक पतला प्रबंधित सी ++ रैपर विकसित कर रहा हूं। मुझे उस बड़ी अप्रबंधित सी ++ लाइब्रेरी में उत्पन्न होने वाली त्रुटियों को पकड़ने की जरूरत है, और उन्हें सीएलआर अपवादों के रूप में पुनर्स्थापित करना होगा। अप्रबंधित पुस्तकालय निम्न वर्ग के उदाहरण फेंकता है:

Error::Error(const std::string& file, long line,
             const std::string& function,
             const std::string& message) {
    message_ = boost::shared_ptr<std::string>(new std::string(
                                  format(file, line, function, message)));
}

const char* Error::what() const throw () {
    return message_->c_str();
}

अब तक मैं इसके साथ आया हूं:

try{
// invoke some unmanaged code
}
catch(Object*)
{
throw gcnew System::Exception("something bad happened");
}

मैं त्रुटि वर्ग से संदेश कैसे निकालूं और इसे Clr स्ट्रिंग वर्ग में कैसे परिवर्तित करूं, ताकि मैं इसे gcnew System::Exception() निर्माता को पास कर सकूं? यदि अप्रबंधित कोड कुछ और फेंकता है, तो क्या मेरा कैच ब्लॉक इसे पकड़ लेगा?

संपादित करें: मैं कैच (ऑब्जेक्ट *) का उपयोग कर रहा हूं क्योंकि वह है एमसीडीएन में अनुशंसित

11
Arne Lund 27 जुलाई 2011, 23:26
यदि Error के उदाहरण फेंके जा रहे हैं, तो आप Object* को क्यों पकड़ रहे हैं? और इस संदर्भ में वैसे भी Object क्या है?
 – 
ildjarn
28 जुलाई 2011, 00:06
@ildjarn: एमएसडीएन पर इस ऑब्जेक्ट * चीज़ की सलाह दी गई थी
 – 
Arne Lund
28 जुलाई 2011, 00:29
यह सी ++ के लिए प्रबंधित एक्सटेंशन के लिए प्रासंगिक है, सी ++/सीएलआई नहीं। दो अलग-अलग भाषाएं, और यह देखते हुए कि आप gcnew का उपयोग कर रहे हैं, आप C++/CLI का उपयोग कर रहे हैं।
 – 
ildjarn
28 जुलाई 2011, 00:31
@ArneLund: साथ ही, एमएसडीएन आलेख Object* द्वारा पकड़ने की अनुशंसा नहीं करता है। यह केवल Object* के बारे में एक चेतावनी कहता है कि यह ठीक से काम नहीं करता
 – 
Mooing Duck
8 अगस्त 2014, 23:35

3 जवाब

सबसे बढ़िया उत्तर

क्या निम्नलिखित आपके लिए काम नहीं करता है?

try
{
    // invoke some unmanaged code
}
catch (Error const& err)
{
    throw gcnew System::Exception(gcnew System::String(err.what()));
}

क्योंकि यह निश्चित रूप से मेरे लिए काम करता है:

#pragma managed(push, off)
#include <string>

struct Error
{
    explicit Error(std::string const& message) : message_(message) { }
    char const* what() const throw() { return message_.c_str(); }

private:
    std::string message_;
};

void SomeFunc()
{
    throw Error("message goes here");
}

#pragma managed(pop)

int main()
{
    using namespace System;

    try
    {
        try
        {
            SomeFunc();
        }
        catch (Error const& err)
        {
            throw gcnew Exception(gcnew String(err.what()));
        }
    }
    catch (Exception^ ex)
    {
        Console::WriteLine(ex->ToString());
    }
    Console::ReadLine();
}
10
ildjarn 28 जुलाई 2011, 00:24
विजुअल स्टूडियो 2017 gcnew, या अपवाद किसी भी सुझाव को नहीं पहचान सकता
 – 
Ali
29 जुलाई 2019, 13:32
: मैं केवल यह मान सकता हूं कि आप किसी कारण से /clr के साथ संकलन नहीं कर रहे हैं। क्षमा करें, मेरे पास इस समय परीक्षण करने के लिए VS स्थापित नहीं है।
 – 
ildjarn
31 जुलाई 2019, 05:08

मैं उपयोग करता हूं

#include <exception>
#include <msclr\marshal.h>

using namespace System;
using namespace msclr::interop;

try
{
    ...
}

catch (const std::exception& e)
{
    throw gcnew Exception(marshal_as<String^>(e.what()));
}

catch (...)
{
    throw gcnew Exception("Unknown C++ exception");
}

आप इसे मैक्रोज़ की एक जोड़ी में रखना चाह सकते हैं क्योंकि उनका उपयोग हर जगह किया जाएगा।

आप अपनी Error कक्षा के साथ एक कस्टम catch ब्लॉक जोड़ सकते हैं, लेकिन चूंकि ऐसा लगता है कि यह std::exception से निकला है, इसलिए जो कोड मैं आपको दिखाता हूं वह ठीक होना चाहिए।

आप अधिक विशेष रूप से std::invalid_argument को पकड़ना और ArgumentException, आदि में अनुवाद करना चाह सकते हैं, लेकिन मुझे यह ओवरकिल लगता है।

5
Alexandre C. 28 जुलाई 2011, 00:17

सबसे अप्रबंधित अपवादों को पकड़ने का एकमात्र विश्वसनीय तरीका है पकड़ (...) अभी भी कुछ अपवाद हैं जो पकड़ (...) को पकड़ नहीं पाएंगे और क्रैश संकेतक के बिना भी आपके एप्लिकेशन को क्रैश कर देंगे (ऐप बस गायब हो जाता है), जैसे कि एक बुरी तरह से लिखा गया तृतीय पक्ष ऐप गलत के साथ सेटजंप/लॉन्गजंप का उपयोग करता है त्रुटि प्रबंधन या थ्रेड प्रोटोकॉल।

यदि आप कई सी ++ अपवाद टाइप करने का प्रयास करना चाहते हैं, तो आप कैच ब्लॉक की एक लंबी श्रृंखला लिख ​​सकते हैं, जैसे:

catch (int i)
{
  // Rethrow managed with int data
}
catch (double d)
{
    // Rethrow managed with double data
}
... etc
catch (...)
{
    // Rethrow managed "I got a general exception" error
}
2
Ed Bayiates 27 जुलाई 2011, 23:41