在 C# 中使用 EHLLAPI 从 IBM 的 Personal Communications iSeries 获取字符串让我得到字符串后跟垃圾
Getting string from IBM's Personal Communications iSeries using EHLLAPI in C# gets me the string followed by garbage
我正在尝试在 as400 模拟器(IBM 的 Personal Communications iSeries)中自动化一个流程,为此,我使用了一些代码(我完全没有从 CodeProject 窃取)它使用 EHLLAPI 连接到模拟器。
我创建了一个 Winforms 来实现带有一些按钮和一些文本框的代码来测试它。
这是 class 公开来自 EHLLAPI 的方法:
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 事件:
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 个字符的字符串:
我得到的垃圾在“字符串结果”上
这是我应该从模拟器获得的区域,只是“Sy”:
这有时有效,有时无效。我尝试了模拟器的不同部分,问题是一样的。获取光标位置并发送字符串工作正常,就在我试图从模拟器获取字符串时。
我什至不知道去哪里寻找答案,因为此代码最初发布于 2005 年。
我发现了问题。在方法 ReadScreen
中,我创建了一个需要 3000 个字符的 StringBuilder
。由于我在方法的参数中使用 out
,因此我处理的是一个内存地址,而不仅仅是两个变量。当我为至少 3000 个字符分配 space 时,当我读取的字符串很小时,有时它会带有来自“未使用”space 的垃圾。我所做的是将 StringBuilder
的预期大小更改为我尝试读取的字符串的长度减去 1(如果它只是长度,我仍然会得到一个垃圾字符)。这是代码:
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 年的,但是这个修改对我有用。如果我误解了什么或者我有什么不对的地方,请随时纠正我。
我正在尝试在 as400 模拟器(IBM 的 Personal Communications iSeries)中自动化一个流程,为此,我使用了一些代码(我完全没有从 CodeProject 窃取)它使用 EHLLAPI 连接到模拟器。
我创建了一个 Winforms 来实现带有一些按钮和一些文本框的代码来测试它。 这是 class 公开来自 EHLLAPI 的方法:
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 事件:
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 个字符的字符串:
我得到的垃圾在“字符串结果”上
这是我应该从模拟器获得的区域,只是“Sy”:
这有时有效,有时无效。我尝试了模拟器的不同部分,问题是一样的。获取光标位置并发送字符串工作正常,就在我试图从模拟器获取字符串时。
我什至不知道去哪里寻找答案,因为此代码最初发布于 2005 年。
我发现了问题。在方法 ReadScreen
中,我创建了一个需要 3000 个字符的 StringBuilder
。由于我在方法的参数中使用 out
,因此我处理的是一个内存地址,而不仅仅是两个变量。当我为至少 3000 个字符分配 space 时,当我读取的字符串很小时,有时它会带有来自“未使用”space 的垃圾。我所做的是将 StringBuilder
的预期大小更改为我尝试读取的字符串的长度减去 1(如果它只是长度,我仍然会得到一个垃圾字符)。这是代码:
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 年的,但是这个修改对我有用。如果我误解了什么或者我有什么不对的地方,请随时纠正我。