使用外部 DLL 时 PL/I 中的错误处理?
Posted
技术标签:
【中文标题】使用外部 DLL 时 PL/I 中的错误处理?【英文标题】:Error handling in PL/I when using an external DLL? 【发布时间】:2013-09-30 13:48:58 【问题描述】:我正在从我的 PL/I 模块调用一个外部 DLL。 DLL 将指向数组的指针作为输入,并返回另一个指向输出数组的指针,以及错误消息和返回代码。
我已经根据从 DLL 得到的返回码进行了适当的错误处理(在我的 PL/I 模块中)。但由于使用了指向数组的指针,我可能有机会在 DLL CSECT 本身中获得 S0C4(即内存/指针执行)。不幸的是,我没有 DLL 的源代码(由于 IP 权利,我们必须将其视为黑匣子),我可以保证异常处理是否已在 DLL 本身内完成。所以目前如果我在 DLL 中遇到异常,我的主模块的 ON ERROR 块会立即捕获该错误,并且批处理会发出 PLIDUMP/CEEDUMP。
我希望以这样一种方式更改我的错误处理方式,即我可以简单地忽略我在 DLL 中遇到内存问题的记录,然后写出一些错误消息并继续处理其余记录,而不是发出PLIDUMP 或 CEEDUMP。
如果我从我的 ON ERROR 块中删除对 PLIDUMP 的调用,那么我将不会从我的 PL/I 代码中获得其他问题的 PLIDUMP(比如数据不匹配,即 S0C7)。
所以我的问题是: 从我的 PL/I 模块访问 TCB 是否可以确定我从哪个 CSECT 得到错误?
否则我想我会在我的 DLL 上编写一些 C++ 包装器,如下所示:
#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);
然后使用catch(std::bad_alloc)
来处理内存异常。
【问题讨论】:
【参考方案1】:我假设您在语言环境 (LE) 下运行。
如果是这样,语言环境条件处理程序可以/应该做你想做的事。
我没有用 PL/I 做过这个,也没有用 DLL。您可以建立仅具有特定条件的处理程序。您可以使用 CEE3GRN 获取导致该条件的程序的例程名称。处理条件后,您可以为要避免的情况安排平稳的延续,并通过将条件“渗透”到下一个控制级别来处理来自不同模块的相同类型的其他条件,这将是任何特定于语言的条件像您的 PL/I ON 一样处理。
有许多可用的演示文稿,以及各种语言环境手册。 PL/I(以及 C 和 COBOL)中有示例程序。用你喜欢的引擎搜索“语言环境条件处理”。
【讨论】:
【参考方案2】:我不是 PL/I 专家,但您能否将 DLL 调用隔离到与主块分开的块中?如果是这样,我相信您可以为该后代块拥有另一个 ON 单元,即 only in effect。
或者,您可以使用condition handling built-in functions 之一来确定发生了哪种错误。也许检查ONCODE() 的结果,看看它是否是8094 or 8095?
【讨论】:
【参考方案3】:您是否尝试过在 ON ERROR 处理函数中使用 PL/I 内置函数 ONLOC 和/或 ONCODE?
如果您上传 PL/I 代码的片段示例而不是 C++ 包装器,这也可能会有所帮助。
【讨论】:
以上是关于使用外部 DLL 时 PL/I 中的错误处理?的主要内容,如果未能解决你的问题,请参考以下文章