Forum > Windows
Access Violation on Procedure Exit
Thaddy:
On Windows CE Pchar <> PAnsiChar but PUnicodeChar/PWideChar. Change all PChar declarations to explicit PAnsiChar and all Chars to explicit AnsiChar.
Last time I programmed for CE is a long time ago, so plz consider that an oversight.
CE is a unicode system since at least CE v6, which means that the string types are interpreted accordingly.
Remy Lebeau:
--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---ReadStringVar(btn[0]); // working, got Messagebox (last line of procedure (Line 202))ShowMessage('test'); // not working, got AV
--- End quote ---
That implies you are corrupting memory or the call stack.
--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;var i: integer;begin Result:= ''; for i:= 0 to length(APlcString) do begin if APlcString[i] <> Chr($00) then Result:= Result + APlcString[i] else exit; end;end;
--- End quote ---
This is a buffer overflow waiting to happen if APlcString is not null-terminated. An open array is 0-indexed, so your loop needs to use length(APlcString)-1 (or High(APlcString)) instead, otherwise you go out of bounds.
Rather than doing a concatenation on every loop iteration, I would suggest using SetString() instead, eg:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;var len: integer;begin for len := 0 to Length(APlcString)-1 do begin if APlcString[len] = Chr($00) then Break; end; SetString(Result, PChar(APlcString), len);end;
Alternatively:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TfrmMain.PlcStringToString(APlcString: array of char): string;begin SetString(Result, PChar(APlcString), Length(APlcString)); Result := TrimRight(Result);end;
--- Quote from: therealhades on May 29, 2024, 01:01:03 pm ---
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmMain.ReadStringVar(var aVar: TStringVar);var tmp: array of char; ads: longint;begin if aVar.Handle = 0 then ads:= AdsSyncReadWriteReq(@AMS, ADSIGRP_SYM_HNDBYNAME, $0000, sizeof(aVar.Handle), @aVar.Handle, Length(aVar.VarName) + 1, @aVar.VarName[1]) else ads:= 0; SetLength(tmp, 255); if ads = 0 then ads:= AdsSyncReadReq(@AMS, ADSIGRP_SYM_VALBYHND, aVar.Handle, Length(tmp), @tmp[0]); if ads = 0 then aVar.Data:= PlcStringToString(tmp); ShowMessage('in Procedure: ' + aVar.Data);end;
--- End quote ---
There is no need to allocate tmp dynamically.
More importantly, a ShortString is not null-terminated, but you are passing in a pointer directly to its characters, and passing in +1 for its length as if a null terminator were present. You need to pass in a valid null-terminated string, eg:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmMain.ReadStringVar(var aVar: TStringVar);var sVarName: AnsiString; tmp: array[0..255] of AnsiChar; ads: longint;begin if aVar.Handle = 0 then begin sVarName := aVar.VarName; ads := AdsSyncReadWriteReq(@AMS, ADSIGRP_SYM_HNDBYNAME, $0000, sizeof(aVar.Handle), @aVar.Handle, Length(sVarName) + 1, PChar(sVarName)); end else ads := 0; if ads = 0 then begin ads := AdsSyncReadReq(@AMS, ADSIGRP_SYM_VALBYHND, aVar.Handle, Length(tmp), @tmp[0]); if ads = 0 then aVar.Data := PlcStringToString(tmp); end; ShowMessage('in Procedure: ' + aVar.Data);end;
In which case, consider changing TStringVar back to using (Ansi)String instead of String[255] for its VarName field:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TStringVar = record VarName: AnsiString; ...end;... ads := AdsSyncReadWriteReq(..., Length(aVar.VarName) + 1, PAnsiChar(aVar.VarName));
Navigation
[0] Message Index
[*] Previous page