C ++ Windows DLL: обработка исключений в разных функциях - PullRequest
0 голосов
/ 10 февраля 2019

Это скорее дизайнерское предложение, которое мне нужно.Ниже приведен код из DLL C ++, над которой я работаю, и эта DLL вызывается многими исполняемыми файлами клиента. InputParams - указатель на exe клиента.

DLL вызывает функции в клиенте для получения определенных значений, и у клиента нет встроенных исключений.Поэтому мне нужно реализовать обработку исключений в коде dll.

для, например, в строке input-> getName , если он возвращает указатель NULL или если status == ОШИБКА, тогда мне нужно сгенерировать исключение и перехватить его в функции GetNumbers .

void Metrics::GetNumbers(InputParams* input, OutputParams* output)
    {
        int i, x, k;
        int status = 0;
        char* mesg;

        try{
             const char* name = input->getName(&status, &mesg); //this returns a name string 
             //and status will contain whether success or failure and mesg will have any error 
             //messages.

             const char* age = input->getAge(&status, &mesg);

            //Many other similar calls to client

             vector <int> myVectorNumers* = input->getNumberArray(&status, &mesg);

             vector <int> myVectorInfos* = input->getInfoArray(&status, &mesg);

            //Many other similar calls to client;
           }
         catch (std::exception e&)
         {
             // TODO
         }
         catch (string msg)
         {
             // TODO
         }

Я нашел способ сделать это.И это фрагмент кода.

string errorMsg = "";
const char* name = input->getName(&status, &mesg); 

if (name == NULL || status == ERROR) // ERROR == 0
{
   errorMsg = mesg;
   throw errorMsg;
}

const char* age = input->getAge(&status, &mesg);

if (age== NULL || status == ERROR)
{
   errorMsg = mesg;
   throw errorMsg;
}

//Same for other calls to client using **input** pointer

Теперь, как вы видите, мне приходится дублировать почти одинаковый код в каждом месте, где должна быть проверка исключений.

Что ищетfor is?

    string errorMsg = "";
    const char* name = input->getName(&status, &mesg); 

    CheckException(name, status, mesg, &errorMsg); // this function should do the error check and then throw the exception. And that exception should be caught by catch block in **GetNumbers** function.

    const char* age = input->getAge(&status, &mesg);

    CheckException(age, status, mesg, &errorMsg);

Понятия не имею, возможно ли даже это.

Так что фиктивная реализация CheckException будет выглядеть ...... ......1028 *

std::exception CheckException (/*1st parameter needs to be template type*/T* var, int status, string mesg, string *errorMsg)
{

    if (var == NULL || status == ERROR)
    {
        errorMsg = mesg;
        return /*TODO*/;  //Not sure how to return a throw
    }
}

1-й, это возможно?Или есть лучший способ сделать это?

Если вы можете предоставить мне пример кода, это будет здорово!

1 Ответ

0 голосов
/ 11 февраля 2019

Исключениям не разрешено передавать через границу DLL в вызывающий исполняемый файл.Вызывающему не гарантируется, что он знает, как правильно обрабатывать исключение, особенно в отношении очистки, даже если исполняемый файл и DLL скомпилированы с одним и тем же компилятором.Или вызывающий может вообще не понимать, что такое исключение, если исполняемый файл и DLL скомпилированы на разных языках.

Если вам нужно передать информацию об ошибке вызывающему, вы должны сделать это с помощью returnзначение, выходной параметр, отдельный вызов функции и т. д. Вещи, которые более или менее универсально поддерживаются в компиляторах / языках.

НЕ бросать исключения через границу DLL в вызывающую программу!

ОБНОВЛЕНИЕ

Вы уже поймали std::exception& в GetNumbers() (хотя вместо этого действительно должно быть const std::exception &), поэтому просто наберите CheckException() на самом деле throw astd::exception объект, не пытайтесь return его, например:

template<typename T>
void CheckException (const T *var, int status, const string &mesg)
{
    if (var == NULL || status == ERROR) {
        // or make a custom class derived from std::exception, if you want...
        throw std::runtime_error(mesg);
   }
}

...

try
{
    const char* name = input->getName(&status, &mesg); 
    CheckException(name, status, mesg);

    const char* age = input->getAge(&status, &mesg);
    CheckException(age, status, mesg);

    // Many other similar calls to client...

    vector<int> *myVectorNumers = input->getNumberArray(&status, &mesg);
    CheckException(myVectorNumers, status, mesg);

    vector<int> *myVectorInfos = input->getInfoArray(&status, &mesg);
    CheckException(myVectorInfos, status, mesg);

    // Many other similar calls to client...
}
catch (const std::exception e&)
{
    // TODO
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...