Indy TIdHashMessageDigest5 HashStringAsHex compile time error: Undeclared identifier: 'HashStringAsHex' - delphi

Using: D7
uses SysUtils, StrUtils, IdHash, IdHashMessageDigest;
..
var
idmd5: TIdHashMessageDigest5;
h, v: string;
begin
idmd5 := TIdHashMessageDigest5.Create;
try
h := idmd5.HashStringAsHex(v);
finally
idmd5.Free;
end;
I have this code which was compiling and running fine earlier in Delphi 7, with the bundled version of Indy. After I upgraded the Indy to the latest version (v10), I am getting the compile time error:
[Error] xxxx.pas(71): Undeclared identifier: 'HashStringAsHex'
Please help!
Additional:
I've solved it by changing
h := idmd5.HashStringAsHex(v);
to:
h := idmd5.AsHex(idmd5.HashValue(v));
However, the above code was in a package (custom component). In my main app, the same corrected code still throws the undeclared identifier when compiling.
This is really confusing now! How can the same code compile in one project, but throw a compile time error in another?!
Update
I've solved it. The component package was using the old Indy library. After removing that reference and updating the source to include the v10 libraries, it now works.

Related

Indy/ssl cannot open file

I'm trying to use ssl with Indy and keep getting the following error:
Project MtApp.exe raised exception class EFOpenError with message 'Cannot open file "C:\Development\MyApp\Win64\Debug\㩃䑜癥汥灯敭瑮作浡牡屵汁呬楨杮即獹潬屧祓䱳杯楓屭祓䱳杯楓䍭湯潳敬坜湩㐶䑜扥杵浜剹潯䍴⹁数m". The system cannot find the file specified'.
It occurs in the IdSSLOpenSSL.pas file in the following function:
function by_Indy_unicode_file_ctrl(ctx: PX509_LOOKUP; cmd: TIdC_INT; const argc: PAnsiChar; argl: TIdC_LONG; out ret: PAnsiChar): TIdC_INT; cdecl;
The argc parameter appears to be passed in correctly. The IDE debugger shows it as "C:\Development\MyApp\Win64\Debug\myRootCA.pem". The problem seems to be when it is cast as a PWideChar and assigned to a String variable:
X509_FILETYPE_PEM:
begin
// Note that typecasting an AnsiChar as a WideChar is normally a crazy
// thing to do. The thing is that the OpenSSL API is based on ASCII or
// UTF8, not Unicode and we are writing this just for Unicode filenames.
LFileName := PWideChar(argc);
LOk := Ord(Indy_unicode_X509_load_cert_crl_file(ctx, LFileName, X509_FILETYPE_PEM) <> 0);
end;
The LFileName variable is 㩃䑜癥汥灯敭瑮作浡牡屵汁呬楨杮即獹潬屧祓䱳杯楓屭祓䱳杯楓䍭湯潳敬坜湩㐶䑜扥杵浜剹潯䍴⹁数m after the cast, causing a FileNotFound exception.
What am I doing wrong?
You did not say which version of Delphi or Indy you are using. But, the code you have shown is not the latest code that is currently in Indy.
What you have described was due to a regression bug that Embarcadero introduced in the Indy release that shipped in RAD Studio 10.3. They fixed that in a patch for RAD Studio 10.3.3:
https://blogs.embarcadero.com/rad-studio-10-3-3-indy-server-ssl-certificate-patch/
https://cc.embarcadero.com/item/30906
I suggest you update to the latest version of Indy from its GitHub repo:
https://github.com/IndySockets/Indy/
https://github.com/IndySockets/Indy/wiki/Updating-Indy

TMapAccess.maReadWrite not defined using DELPHI 11

the code fragment below works fine for DELPHI 10.4 and FMX framework, but does not compile using DELPHI 11 . Error : maReadWrite not defined
[dcc64 Error] ImageUnit.FMX.pas(5340): E2003 Undeclared identifier: 'maReadWrite'
How to solve this issue and how to write code which compiles using DELPHI 10.4 and DELPHI 11 ?
var bit : TBitmap;
begin
if (Bit.Map(TMapAccess.maReadWrite, bitdata1)) then
try
for i := 0 to Bit.width - 1 do
for j := 0 to Bit.height - 1 do
begin
The TMapAccess values that begin with the ma prefix were deprecated before 10.4 to drop the prefix (ie maRead -> Read, maWrite -> Write, maReadWrite -> ReadWrite). You should have gotten compiler warnings about this in 10.4.
The prefixed values were finally removed completely in 11.0 Alexandria.
So, the correct way to write this code for both versions is to simply use the newer non-prefixed value names, eg:
if (Bit.Map(TMapAccess.ReadWrite, bitdata1)) then

Delphi XE 10.1 JVCL Installation Failed

I have installed the latest JCL 2016-10-10
and I want to install the latest JVCL, but I'm getting some error messages.
How I can install it?
Windows 10 Home (10.0.0)
JVCL 3.50.0.0
[Generating: Packages]
Generating packages for D24
Loaded template.dpk
Loaded template.dproj
Loaded template.rc
[Compiling: Packages]
[Compiling: JvCore240.bpl]
Embarcadero Delphi for Win32 compiler version 31.0
Copyright (c) 1983,2016 Embarcadero Technologies, Inc.
E:\DelphiComp\XE10.1\JVCL3-2016-10-10\run\JvAppIniStorage.pas(261) Error: E2361 Cannot access private symbol TMemIniFile.FSections
E:\DelphiComp\XE10.1\JVCL3-2016-10-10\run\JvAppIniStorage.pas(261) Warning: W1023 Comparing signed and unsigned types - widened both operands
E:\DelphiComp\XE10.1\JVCL3-2016-10-10\run\JvAppIniStorage.pas(261) Error: E2014 Statement expected, but expression of type 'Boolean' found
E:\DelphiComp\XE10.1\JVCL3-2016-10-10\run\JvAppIniStorage.pas(274) Error: E2361 Cannot access private symbol TMemIniFile.FSections
JvCore.dpk(2356) Fatal: F2063 Could not compile used unit 'JvAppIniStorage.pas'
The Delphi 10.1 Berlin version removed the access of private members through class helpers (see How to access private methods without helpers?). That is the error message you can see, when access to TMemIniFile.FSections is denied.
Looking at the latest code for JvAppIniStorage.pas, this is fixed:
{ Optimization of TCustomIniFile.ValueExists.
Note that this is a dirty hack, a better way would be to rewrite TMemIniFile;
especially expose FSections. }
{$IFDEF DELPHI2009_UP}
type
TMemIniFileAccess = class(TCustomIniFile)
{$IFDEF RTL310_UP} // 10.1 Berlin removed the access to private fields
{$IFDEF RTL320_UP}
{$MESSAGE WARN 'Check that the new RTL still has FSections as the first member of TMemIniFile'}
{$ENDIF RTL320_UP}
private
FSections: TStringList;
{$ENDIF RTL310_UP}
end;
As said in code comments, this is a dirty hack that works if the FSections still is declared as the first field in TCustomIniFile.
And in code:
function TMemIniFileHelper.SectionExists(const Section: string): Boolean;
begin
{$IFDEF RTL310_UP} // 10.1 Berlin removed the access to private fields
Result := TMemIniFileAccess(Self).FSections.IndexOf(Section) >= 0;
{$ELSE}
Result := Self.FSections.IndexOf(Section) >= 0;
{$ENDIF RTL310_UP}
end;
Make sure you have the latest source for jvcl and recompile. Note that the symbol RTL310_UP is defined in jedi.inc.

FMX.Grid.TColumn.CellControlByRow function

I tried to compile file FMXTee.Chart.Grid.pas from TeeChart 9 for XE10 that used CellControlByRow function in FMX.Grid.pas for the following code :
with TColumnAccess(Columns[Col]).CellControlByRow(Row).BoundsRect.BottomRight do begin ... end;
I get running well when using RAD XE10 Seattle, and now I tried with RAD XE10.1 Berlin but get error message : [dcc32 Error] FMXTee.Chart.Grid.pas(1507): E2003 Undeclared identifier: 'CellControlByRow'
Then I compare file FMX.Grid.pas from XE10 packages versus FMX.Grid.pas from XE10.1 packages, and there are a lot of differences especially CellControlByRow() function does not exist any more in FMX.Grid.pas from XE10.1.
Now, I want ask how to change the code that use CellControlByRow function so it will run in RAD XE10.1 Berlin ?
I would like suggest you replace the code below:
result:=TColumnAccess(Columns[Col]).CellControlByRow(Row).BoundsRect.BottomRight;
For next :
...
var tmp : TFmxObject;
begin
tmp:=TColumnAccess(Columns[Col]).CellControl;
result:=TControl(tmp).BoundsRect.BottomRight
...
The above code should fix the compilation problem you’re experiencing. Could you confirm that?

how to make HTTPS calls on the iOS simulator Delphi seattle

OpenSSL not working for iOS Simulator in Delphi DX
Using info at:
http://blog.marcocantu.com/blog/using_ssl_delphi_ios.html
http://docwiki.embarcadero.com/RADStudio/Seattle/en/OpenSSL
https://plus.google.com/100777187605111792758/posts/SPnHdXvTTNu
I can get it to work on devices, but not on the iOS simulator. Same URL works when I use a TWebbrowser.navigate, but not with INDY of course.. See below, and possibly offer suggestions on how to make HTTPS calls on the iOS simulator ! This worked before in earlier versions of Rad Studio ( XE4, XE5 ) but hasnt since XE7 if my memory has served me right.
I have these files in my usr/lib folder:
libcrypto.0.9.8.dylib
libssl.0.9.8.dylib
Here is my uses
uses
IdSSLOpenSSL,
{$IF Defined(IOS) and Defined(CPUARM)}
IdSSLOpenSSLHeaders_Static,
{$ELSE}
IdSSLOpenSSLHeaders,
{$ENDIF}
...
Here is my onCreate for the main form
procedure TmLoginForm.FormCreate(Sender: TObject);
var
t:string;
begin
IdOpenSSLSetLibPath('/usr/lib/');
...
Here is part of a function that I use, where on the last line an exception is thrown
function ParseGroups(OnlyUserCreated:boolean):integer;
var
IdHTTP :TIdHTTP;
HTML :String;
JSON_Groups :TJSONObject;
Group :uGroup;
begin
result:=0;
HTML:='';
IdHTTP:=TIdHTTP.Create(nil);
IdHTTP.HandleRedirects:=false;
try
HTML:=IdHTTP.Get(URL_Host+ACCESSTOKEN);
Error is: 'Could Not Load SSL Library'
ShowMessage(IdSSLOpenSSLHeaders.WhichFailedToLoad); shows a blank message
Update:
adding
IdSSLOpenSSLHeaders.Load;
after setting the path now causes the whichFailedToLoad say: 'Failed to Load /usr/lib/libcrypto.'
Use System.Net.HttpClient.THTTPClient instead of the Indy components.
var
http : THTTPClient;
html : string;
http := THTTPClient.Create;
try
html := http.Get( url ).ContentAsString();
...
finally
http.Free;
end;
It is a wrapper of the http function from the operating system. If the OS supports https, then this class will do also.
You can also follow this nifty blogpost http://delphiworlds.com/2016/03/building-openssl-dylibs-for-ios-simulator/
It worked just fine for me. I needed it, because my Soap client needs to connect via https, and I did not want to rewrite the soap libs.

Resources