Обработка ошибок в PL/I при использовании внешней DLL?

Я вызываю внешнюю DLL из моего модуля PL/I. DLL принимает указатель на массив в качестве входных данных и возвращает другой указатель на выходной массив вместе с сообщением об ошибке и кодом возврата.

Я сделал подходящую обработку ошибок (в моем модуле PL/I) на основе кода возврата, который я получаю из DLL. Но поскольку используется указатель на массивы, могут быть шансы, что я смогу получить S0C4 (т.е. исключения памяти/указателя) в самой DLL CSECT. К сожалению, у меня нет исходного кода для DLL (поскольку мы должны обращаться с ним как с черным ящиком из-за прав IP), что я могу гарантировать, если обработка исключений была выполнена в самой DLL. Итак, в настоящее время, если я получаю исключение внутри DLL, ошибка сразу фиксируется моим блоком ON ERROR моего основного модуля, и пакет выдает PLIDUMP/CEEDUMP.

Я хочу изменить свою обработку ошибок таким образом, чтобы я мог просто игнорировать записи, для которых у меня возникают проблемы с памятью внутри DLL, затем выводить некоторые сообщения об ошибках и просто продолжать работу с остальными записями вместо выдачи PLIDUMP или CEEDUMP.

Если я уберу вызов PLIDUMP из моего блока ON ERROR, то я не получу PLIDUMP для других проблем (скажем, таких как несоответствие данных, то есть S0C7) из моего кода PL/I.

Итак, мои вопросы: Может ли доступ к TCB из моего модуля PL/I быть способом, с помощью которого я могу определить, из какого CSECT я получаю свою ошибку?

В противном случае я думаю, что напишу обертку C++ поверх моей DLL, как показано ниже:

#include "dllexp.h"
#pragma export(CARSDLL)

int DLLEXPORT CARSDLL(
 double *dpInputVector, int iInputVectorLength,
 double *dpOutputVector, int iOutputVectorLength,
 char *szMsgBuffer, int iMsgBufferLength)
{

 return risks_msg(dpInputVector, iInputVectorLength,
                  dpOutputVector, iOutputVectorLength,
                  szMsgBuffer, iMsgBufferLength);
}

а затем используйте a catch(std::bad_alloc) для обработки исключений памяти.


person Soumik Das    schedule 30.09.2013    source источник


Ответы (3)


Я предполагаю, что вы работаете в языковой среде (LE).

Если это так, обработчик условий языковой среды может/должен делать то, что вы хотите.

Я не делал этого ни с PL/I, ни с DLL. Вы можете установить обработчик только с определенными условиями. Вы можете использовать CEE3GRN для получения обычного имени программы, вызывающей состояние. Как только условие обработано, вы можете организовать плавное продолжение того, чего вы хотите избежать, и обрабатывать другие условия того же типа из разных модулей, «передавая» условие на следующий уровень управления, которым может быть любое условие, специфичное для языка. управляемость как у вашего PL/I ON.

Доступен ряд презентаций, а также различные руководства по языковой среде. Есть примеры программ на PL/I (а также на C и COBOL). Найдите «обработку условий языковой среды» с помощью вашего любимого движка.

person Bill Woodger    schedule 02.10.2013

Я не эксперт по PL/I, но можете ли вы изолировать вызовы DLL в блоки, отдельные от основного блока? Если это так, я считаю, что у вас может быть другой модуль ON, который действует только для этого дочернего блока.

В качестве альтернативы вы можете использовать один из встроенные функции обработки условий, чтобы определить тип возникшей ошибки. Возможно, проверка результата ONCODE(), чтобы узнать, является ли он 8094 или 8095?

person cschneid    schedule 30.09.2013

Пробовали ли вы использовать встроенную функцию PL/I ONLOC и/или ONCODE из вашей функции обработки ON ERROR?

Также может помочь загрузка фрагмента кода PL/I вместо оболочки C++.

person MikeC    schedule 02.10.2013