The younger brother has recently been doing .NET's serial communication program, there is no self-contained serial control under .NET, use the previous COM components and unwilling, so I found SAX.NET component (crack) version, use Time, more satisfied, but in the process of use,
System.ArgumentOutofrangeException: The length cannot be less than 0.
Parameter name: Newlength
At system.text.stringbuilder.set_length (int32 value)
At Sax.communications.SerialConnection.a (UINT
32 a
_0)
At Sax.communications.SerialConnection.a (INTPTR A_0, C & A_1)
At SAX.communications.serialConnection.get_available ()
At sax.communications.serialConnection.b ()
Exceptions, especially when using ISP lines to communicate with single chip, there will be exceptions every time the ISP line. After an abnormality, the control's serial data monitoring thread will never send and receive data before exiting, and can only restart the software. After careful debugging, it is found that the abnormality appears when the data line is plugged, and there is data received, generating the processing function when the private void serialconnection_dataavailable (Object Sender, Eventargs E) // is subject to data {// before this Abnormal INT length = serialconnection.available; // debug.writeline (length (length <= 0) return; byte [] buffer = new byte [length]; // How much data is input buffer ? SerialConnection.Read (Buffer, 0, Length); // Analyzes Data IF (Length> 0) {HandleDataReceive (Buffer);}} After the event occurs, in Int length = SerialConnection.available; previous exceptions. According to the prompt information of VS.NET, it is initially determined that when it is set to a StringBuilder object Builder, the incoming parameter <0 is caused. Ok, use the .NET's anti-compilation tool Reflector (I used the version
4.0.18
) Open the control, find the SerialConnection class; because this control is confused, there is a lot of functions such as A, or B, such as A, or B, which appear after the anti-compilation. However, there is no relationship, because abnormal appears near SerialConnection.available, find the realization code of Available directly
Public override int GET_AVAILABLE ()
{
Z.C C1;
THIS.C ();
C1 = new z.c ();
THIS.A (THIS.A, REF C1);
IF (this.b! = -1)
{
Return ((int) (c1.b 1));
}
Return ((int) c1.b);
}
Find the error in this, find this.a (this.a, ref c1); this
Private string a (INTPTR A_0, Ref Z.C A_1)
{
UINT NUM1 = 0; z.clearcommerror (A_0, Ref Num1, REF A_1);
IF (Num1! = 0)
{
Return this.a (Num1);
}
Return NULL;
}
There is tracking to return this.a (Num1);
Private string a (uint a_0)
{
Stringbuilder Builder1 = New StringBuilder ("UART Error:", 60);
IF (Builder1.Length <= 0)
{
Goto label_
005f
;
}
Goto label_00d0;
Label_001b:
Builder1 = Builder1.Append ("Parity,");
Goto label_00b1;
Label_
002c
:
Builder1 = Builder1.Append ("Receive overflow,");
Goto label_0069;
Label_003d:
Builder1 = Builder1.Append ("framing,");
Goto label_0095;
Label_004e:
Builder1 = Builder1.Append ("Transmit overflow,");
Goto label_
00A
3;
Label_
005f
:
IF ((A_0 & 8) == 0)
{
Goto label_0095;
}
Goto label_003d;
Label_0069:
IF ((A_0 & 4) == 0)
{
Goto label_00b1;
}
Goto label_001b;
Label_0073:
Builder1 = Builder1.Append ("
Goto label_00fa;
Label_0084:
Builder1 = Builder1.Append ("overrun,");
Goto label_00ed;
Label_0095:
IF ((A_0 & 1024) == 0)
{
Goto label_00e3;
}
Goto label_00bf;
Label_
00A
3:
IF ((A_0 & 1287) == 0)
{
Goto label_00fa;
}
Goto label_0073;
Label_00b1:
IF ((A_0 & 256) == 0)
{
Goto label_
00A
3;
}
Goto label_004e;
Label_00bf:
Builder1 = Builder1.Append ("IO,");
Goto label_00e3;
Label_00d0:
Builder1.Remove (0, Builder1.Length);
Goto label_
005f
;
Label_00e3:
IF ((A_0 & 2)! = 0)
{
Goto label_0084;
}
Label_00ed:
IF ((A_0 & 1) == 0)
{
Goto label_0069;
}
Goto label_
002c
;
Label_00fa:
Builder1.Length - = 1; // !!!!!!!!!!!!!!!!!! Wrong source
Return Builder1.toString ();
}
I rely on, I don't want to read why Builder1.Length minus 1, save memory, is there necessary? ! ! Anyway, this sentence is wrong, and after the Builder1.Length is less than 0. The previous code is not to assign the statement to builder1.length. It seems that this sentence will be changed, check the IL code, the last few words are L_00fa: LDLOC
.0
L
_00fb: ldloc
.0
L
_00FC: Callvirt Stringbuilder.get_lengthl_0101: LDC.I4.1 // Load constant 1 - Change this to load constant 0, ie L_0102: SUB L_0103: CallVirt stringbuilder.set_lengthl_0108: ldloc
.0
L
_0109: Callvirt stringbuilder.tostringl_010e: RET Find IL assembly instructions Discovery (format instruction --- Hexadecimal number) ldloc.0 ---- 06ldloc.0 ---- 06callvirt stringbuilder.get_length ----
6F
X x x x (x does not know the specific value, you can configure the instruction to modify in the file) LDC.i4.1 ---- 17
SUB ----
59
L_0103: Callvirt ---- StringBuilder.Set_LENGTH
6F
X x xl_0108: ldloc.0 ----
06
L_0109: Callvirt ---- StringBuilder.toString
6F
X x xl_010e: RET ---- 28
Use WinHex to open the file, use the 16-backed search, find the offset 0x34b0 for the above X x using the fuzzy match, change 0x17 at 0x34BD to 0x16 (IL instruction ldc.i4.0, is equal to Length-0 equal to Not reduced) The deployment is exited, and the modified DLL file will overwrite the original DLL, run the software, how to swap the ISP line without problems! Reference INSIDE Microsoft. NET IL Assesmbler