首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中使用EHLLAPI从IBM iSeries获取字符串将得到字符串,后面是垃圾信息

在C#中使用EHLLAPI从IBM iSeries获取字符串将得到字符串,后面是垃圾信息
EN

Stack Overflow用户
提问于 2021-10-14 18:20:32
回答 1查看 207关注 0票数 2

我正试图在as400模拟器(ISeries iSeries)中自动化一个进程,为此,我使用了一些使用EHLLAPI连接到模拟器的代码(我完全不是从CodeProject窃取的)。

我创建了一个Winforms来实现代码,使用一些按钮和一些文本框来测试它。下面是从EHLLAPI公开方法的类:

代码语言:javascript
复制
public class EhllapiFunc //Class used to import the DLL.
{
    [DllImport("PCSHLL32.dll")]
    public static extern UInt32 hllapi(out UInt32 Func, StringBuilder Data, out UInt32 Length, out UInt32 RetC);
}

class EhllapiWrapper
{
    /*These are the constants used to as function codes that are sent as parameters to the function in the DLL. 
    There are a lot more constants but these are the only ones used for the moment*/
    const UInt32 HA_CONNECT_PS = 1; /* 000 Connect PS*/
    const UInt32 HA_DISCONNECT_PS = 2; /* 000 Disconnect PS*/
    const UInt32 HA_COPY_PS_TO_STR = 8; /* 000 Copy PS to String*/
    
    /*EHLLAPI return codes. There are a lot more. I'll leave just some of them as I'm not getting any return codes in my issue*/
    const UInt32
        HARC_SUCCESS = 0; /* 000 Good return code.*/
    const UInt32
        HARC99_INVALID_INP = 0; /* 000 Incorrect input*/
    const UInt32
        HARC_INVALID_PS = 1; /* 000 Invalid PS, Not*/
    const UInt32
        HARC_BAD_PARM = 2; /* 000 Bad parameter, or*/
    
    //Method to connect to the emulator.
    public static UInt32 Connect(string sessionID)
    {
        StringBuilder Data = new StringBuilder(4);
        Data.Append(sessionID);
        UInt32 rc = 0;
        UInt32 f = HA_CONNECT_PS;
        UInt32 l = 4;
        return EhllapiFunc.hllapi(out f, Data, out l, out rc);
    }

    //Method to disconnect.
    public static UInt32 Disconnect(string sessionID)
    {
        StringBuilder Data = new StringBuilder(4);
        Data.Append(sessionID);
        UInt32 rc = 0;
        UInt32 f = HA_DISCONNECT_PS;
        UInt32 l = 4;
        return EhllapiFunc.hllapi(out f, Data, out l, out rc);
    }

    /*This is the method where I'm having the problem.*/
    public static UInt32 ReadScreen(int position, int len, out string txt)
    {
        StringBuilder Data = new StringBuilder(3000);
        UInt32 rc = (UInt32)position;
        UInt32 f = HA_COPY_PS_TO_STR;
        UInt32 l = (UInt32)len;
        UInt32 r = EhllapiFunc.hllapi(out f, Data, out l, out rc);
        txt = Data.ToString();
        return r;
    }
}

这是我用来调用表单上的方法的OnClick事件:

代码语言:javascript
复制
private void bReadString_Click(object sender, EventArgs e)
{
    //I tried cleaning the TextBox where the outputed string is sent before calling the method.
    tbReadOut.Text = "";
    string s;
    //I send the position and string length entered on the form to the method and then "s" is modified inside the method "ReadScreen".
    EhllapiWrapper.ReadScreen(Convert.ToInt32(tbReadPos.Text), Convert.ToInt32(tbReadLen.Text), out s);
    tbReadOut.Text = s;
}

下面是这个问题的一个例子。我应该从光标位置“30”得到一个2个字符大小的字符串:

我得到的垃圾信息是"String Result“

这是我应该从模拟器中得到的区域,只需要"Sy":

我尝试了模拟器的不同部分,发现问题是一样的。获取光标位置并发送字符串工作得很好,这只是在我试图从仿真器获取字符串时。

我甚至不知道去哪里寻找答案,因为这段代码最初是在2005年发布的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-15 13:52:43

我找到问题了。在ReadScreen方法中,我创建了一个需要3000个字符的StringBuilder。当我在该方法的参数中使用out时,我处理的是一个内存地址,而不仅仅是两个变量。当我为至少3000个字符分配空间时,当我读取的字符串很小时,有时它会带有来自“未使用”空间的垃圾。我所做的是将StringBuilder的预期大小更改为我试图读取的字符串的长度减去1(如果只是这个长度,我仍然会得到一个垃圾字符)。代码如下:

代码语言:javascript
复制
public static UInt32 ReadScreen(int position, int len, out string txt)
{
    StringBuilder Data = new StringBuilder(len - 1); //This line was the problem.
    UInt32 rc = (UInt32)position;
    UInt32 f = HA_COPY_PS_TO_STR;
    UInt32 l = (UInt32)len;
    UInt32 r = EhllapiFunc.hllapi(out f, Data, out l, out rc);
    txt = Data.ToString();
    return r;
}

我的解释可能是错误的,因为我还在学习C#,代码最初是2005年的,但这个修改对我来说是有效的。如果我误解了什么或者我做错了什么,请随时纠正我。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69575573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档