DSNAME长度为的IBM窗口服务(DWS)CSRIDAC无效
我正在开发z/OS,并尝试使用IBM提供的窗口服务。 除了通过DSNAME创建对象外,其他一切都能正常工作 当我使用DSNAME调用CSRIDAC时,出现错误: “系统无法分配或取消分配 指定为对象名称的数据集。值rrrr是返回代码 来自动态分配。值nnnn是两字节原因 来自动态分配的代码。请参阅z/OS MVS编程: 动态分配返回的授权汇编程序服务指南 以及原因代码。” 因此,我搜索原因码037c的含义,发现:“文本单元中指定的LEN无效。附带的消息IKJ56231I表示错误的文本单元编号。” 因此,窗口服务似乎正在调用动态分配服务以按其DSNAME创建对象,并且在计算我提供的DSNAME中的字符数时出错 我的DSNAME是一个有效的VSAM文件名,我使用相同的DSNAME通过另一种方式成功地读取了此数据集 下面是调用CSRIDAC函数的函数代码:DSNAME长度为的IBM窗口服务(DWS)CSRIDAC无效,c,zos,mvs,C,Zos,Mvs,我正在开发z/OS,并尝试使用IBM提供的窗口服务。 除了通过DSNAME创建对象外,其他一切都能正常工作 当我使用DSNAME调用CSRIDAC时,出现错误: “系统无法分配或取消分配 指定为对象名称的数据集。值rrrr是返回代码 来自动态分配。值nnnn是两字节原因 来自动态分配的代码。请参阅z/OS MVS编程: 动态分配返回的授权汇编程序服务指南 以及原因代码。” 因此,我搜索原因码037c的含义,发现:“文本单元中指定的LEN无效。附带的消息IKJ56231I表示错误的文本单元编号。”
ozwinsrvObject *ozwinsrvObjectCreate(uint32_t uiFlags, int32_t iObjectSize, uint8_t *pcObjectName, int32_t *piHighOffset, int32_t *piRc)
{
ozwinsrvObject *pobject = __malloc31(sizeof(ozwinsrvObject));
*piRc = OZWINSRV_NO_ERROR;
pobject->pheap = __malloc31(18*4);
pobject->pparmList = __malloc31(11 * sizeof(int32_t));
memcpy(&pobject->parmObject.acOpType[0] , "BEGIN", 5);
pobject->parmObject.iObjectSize = iObjectSize;
pobject->parmObject.iHighOffset = *piHighOffset;
if(uiFlags & OZWINSRV_OBJECT_F_TYPE_DDNAME)
{
memcpy(&pobject->parmObject.acObjectType[0], "DDNAME ", 9);
}
else {
if(uiFlags & OZWINSRV_OBJECT_F_TYPE_DSNAME)
{
memcpy(&pobject->parmObject.acObjectType[0], "DSNAME ", 9);
}
else
{
memcpy(&pobject->parmObject.acObjectType[0], "TEMPSPACE", 9);
}
}
if(uiFlags & OZWINSRV_OBJECT_F_SCROLL_AREA_YES)
{
memcpy(&pobject->parmObject.acScrollArea[0], "YES", 3);
}
else
{
memcpy(&pobject->parmObject.acScrollArea[0], "NO ", 3);
}
if(uiFlags & OZWINSRV_OBJECT_F_STATE_NEW)
{
memcpy(&pobject->parmObject.acObjectState[0], "NEW", 3);
}
else
{
memcpy(&pobject->parmObject.acObjectState[0], "OLD", 3);
}
if(uiFlags & OZWINSRV_OBJECT_F_ACCESS_MODE_UPDATE)
{
memcpy(&pobject->parmObject.acAccessMode[0], "UPDATE", 6);
}
else
{
memcpy(&pobject->parmObject.acAccessMode[0], "READ ", 6);
}
memcpy(&pobject->acObjectName[0], pcObjectName, strlen(pcObjectName));
if(strlen(pcObjectName) < 45)
{
pobject->acObjectName[strlen(pcObjectName)] = ' ';
}
memset(pobject->pparmList, 0, 11 * sizeof(int32_t));
pobject->pparmList[0] = (int32_t) &pobject->parmObject.acOpType[0];
pobject->pparmList[1] = (int32_t) &pobject->parmObject.acObjectType[0];
pobject->pparmList[2] = (int32_t) &pobject->parmObject.acObjectName[0];
pobject->pparmList[3] = (int32_t) &pobject->parmObject.acScrollArea[0];
pobject->pparmList[4] = (int32_t) &pobject->parmObject.acObjectState[0];
pobject->pparmList[5] = (int32_t) &pobject->parmObject.acAccessMode[0];
pobject->pparmList[6] = (int32_t) &pobject->parmObject.iObjectSize;
pobject->pparmList[7] = (int32_t) &pobject->acObjectId[0];
pobject->pparmList[8] = (int32_t) &pobject->parmObject.iHighOffset;
pobject->pparmList[9] = (int32_t) &pobject->parmObject.iRc;
pobject->pparmList[10] = (int32_t) &pobject->parmObject.iReasonC;
x6csridac(pobject->pparmList, pobject->pheap);
if(pobject->parmObject.iRc != 0)
{
printf("Error creating object (csridac) Rc=0x%x, ReasonC=0x%x\n", pobject->parmObject.iRc, pobject->parmObject.iReasonC);
*piRc = OZWINSRV_ERROR_WINDOW_OBJECT_CREATE;
}
*piHighOffset = pobject->parmObject.iHighOffset;
pobject->iObjectSize = iObjectSize;
pobject->uiFlags = uiFlags;
pobject->uiNbViews = 0;
return pobject;
}
int32_t iRc = 0;
int32_t iPageSize = 32*1024;
int32_t iPageOffset = iPageSize/4/1024;
int32_t iSize = 1;
int32_t iRealSize = 1;
ozwinsrvObject *pObject;
ozwinsrvWindow *pWindow;
uint8_t acFileName[] = "DSNB10.DSNDBC.DBTLS00.TS1449.I0001.A001";
pObject = ozwinsrvObjectCreate(OZWINSRV_OBJECT_F_ACCESS_MODE_READ | OZWINSRV_OBJECT_F_SCROLL_AREA_NO | OZWINSRV_OBJECT_F_STATE_OLD | OZWINSRV_OBJECT_F_TYPE_DSNAME,
iSize, &acFileName[0], &iRealSize, &iRc);
我希望我对这个问题的解释是清楚的。如果不是的话,请随意提问。
谢谢 我发现了错误并发布了答案。 我使用以下行复制数组中的名称:
memcpy(&pobject->acObjectName[0], pcObjectName, strlen(pcObjectName));
但是!当我将此数组放入参数列表时,我使用以下代码行:
pobject->pparmList[2] = (int32_t) &pobject->parmObject.acObjectName[0];
这意味着名称在POObject->acObjectName中,我将POObject->parmObject.acObjectName放在参数列表中。这两个数组不是相同的变量
我为我的错误感到抱歉,并确认DWS运行良好。我不会将此作为答案发布,因为这只是一个猜测,我无法测试它。数据集名称中可能有来自未初始化堆区域的尾随垃圾。CSRIDAC文档说“将对象名称定义为长度为1到44的字符数据。如果对象名称包含的字符少于44个,请在右侧用空格填充名称。”。您的
if
语句只将NUL设置为一个空格,因此可能存在尾部垃圾。我会添加一个memset(&pobject->acObjectName[0],“”,sizeof(acObjectName))代码>(假设sizeof(acObjectName)为44,否则为硬代码44)在acObjectName memcpy之前。这会在移动前将整个区域初始化为空格,因此,当您仅移动输入参数的strlen
时,超过NUL的区域仍然是空格。然后您可以将NUL设置为空格,现在您有了一个有效的44字节区域和一个数据集名称。需要记住的一点是,这些接口中有许多是在C语言之前设计的,因此您必须考虑整个字段的最大长度必须是什么样子(特别是对于DD名称和DSN之类的问题。如果这解决了您的问题,请告诉我们,我会写下来作为答案。我尝试了您的解决方案,但没有解决我的问题。我不确定问题最终来自DSNAME…Windows服务可能会向动态分配服务发送多个文本单元。问题是我不知道是哪个文本单元引发了错误。有没有办法对此进行一些日志或详细说明?一种方法是对动态分配错误进行系统转储(如果您不知道如何进行,请阅读《IBM语言环境调试指南》中关于DYNDUMP和SYSMDUMP的内容)。获得转储后,找到跟踪表,并在转储之前找到SVC 99跟踪条目-这是动态分配。SVC条目的R1将具有dynalloc参数列表(希望也会在转储中)从那里,你可能会发现什么是错的。好吧,该死的。不过,我还是会保留它,以确保你有44字节的合法数据作为数据集名称。接下来按照Valerie的建议(转储)。我们可以帮助你解释SVC 99文本单位(如果你是受虐狂,这很有趣)。