Question

I am calling an external DLL from my PL/I module. The DLL takes a pointer to an array as an input and returns another pointer to an output array, alongwith an error message and a return code.

I have done suitable error handling (in my PL/I module) based on the return code I get back from the DLL. But since there is usage of pointer to arrays, there might be chances that I can get a S0C4 (i.e. memory/pointer execptions) within the DLL CSECTs itself. Unfortunately, I do not have the source code for the DLL (as we have to treat it like a black box due to IP rights), that I can guarantee if exception handlings have been done within the DLL itself. So currently if I get an exception inside the DLL, the error is straightaway captured by my ON ERROR block of my main module and the batch issues a PLIDUMP/CEEDUMP.

I wish to change my error handling in such a manner that I can simply ignore the records for which I get memory issues inside the DLL then write some error messages out and simply continue with the rest of the records, instead of issuing a PLIDUMP or a CEEDUMP.

If I remove the call to PLIDUMP from my ON ERROR block then I would not get the PLIDUMP for other issues (say like a data mismatch i.e. S0C7) from my PL/I code.

So my questions is: Accessing the TCB from my PL/I module can there be a way that I can determine from which CSECT I am getting my error?

Else I think I will write some C++ wrapper over my DLL like below:

#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);
}

and then use a a catch(std::bad_alloc) to handle memory exceptions.

Was it helpful?

Solution

I assume that you are running under Language Environment (LE).

If so, a Language Environment Condition Handler could/should do what you want.

I've not done this with PL/I, nor with a DLL. You can establish an handler with only specific conditions. You can use CEE3GRN to Get Routine Name of the program causing the condition. Once the condition is handled you can arrange a smooth continuation for what you want to avoid, and handle other conditions of the same type from different modules by "percolating" the condition to the next level of control, which would be any language-specific condition handling like your PL/I ON.

There are a number of presentations available, plus the various Language Environment manuals. There are example programs in PL/I (and C and COBOL). Search for "language environment condition handling" with your favourite engine.

OTHER TIPS

I am no PL/I expert, but can you isolate your DLL calls into blocks separate from your main block? If so, I believe you can have another ON unit that is only in effect for that descendent block.

Alternatively, you might be able to use one of the condition handling built-in functions to determine what sort of error occurred. Perhaps checking the result of ONCODE() to see if it is 8094 or 8095?

Have you tried using the PL/I Builtin function ONLOC and/or ONCODE from within your ON ERROR handling function?

It might also help if you upload a fragment example of your PL/I code instead of the C++ wrapper.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top