DanishMale
Members-
Content Count
8 -
Joined
-
Last visited
Community Reputation
0 NeutralRecent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
I have this DLL: library WEB; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses ShareMem, SysUtils, Variants, Classes, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent, StrUtils; const BrowserAgent: Array[0..1] of String = ( // Add as many as you wish 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582' ); var NetHTTPClient1: TNetHTTPClient; theResponse: TStream; theHeader: TNetHeaders; HeaderArray: TStrings; DummyValue: String; {$R *.res} function Split(Delimiter: Char; Str: string): TStrings; var ListOfStrings: TStringList; begin ListOfStrings := TStringList.Create; ListOfStrings.Delimiter := Delimiter; ListOfStrings.StrictDelimiter := True; // Requires D2006 or newer. ListOfStrings.DelimitedText := Str; Result := ListOfStrings; end; function GetHTTP(theURL,theHeaders, theOptions: PChar): PChar; {$ifdef win32} Stdcall;{$endif} Export; var I: Integer; begin if theURL <> '' then begin try theHeader := TNetHeaders.Create(); theResponse := TStream.Create; NetHTTPClient1 := TNetHTTPClient.Create(nil); NetHTTPClient1.AcceptCharSet := 'UTF-8'; NetHTTPClient1.UserAgent := BrowserAgent[Random(2)]; try if theHeaders <> '' then begin HeaderArray := Split('|',String(theHeaders)); for I := 0 to HeaderArray.Count - 1 do begin theHeader[I].Value := HeaderArray[I]; end; end; if UpperCase(theOptions) = 'YES' then begin DummyValue := PChar(NetHTTPClient1.Options(String(theURL),theResponse,theHeader).StatusText); end; Result := PChar(NetHTTPClient1.Get(String(theURL),theResponse, theHeader).ContentAsString()); except on E : Exception do Result := PChar('<html><head><title>Error page - '+E.ClassName+'</title></head>'+ '<body bgcolor="#ffffff" leftmargin="0" topmargin="0" '+ 'marginwidth="0" marginheight="0"><table width="75%" '+ 'border="0" cellpadding="50" cellspacing="0"><tr>'+ '<td><h3>Request error - '+E.ClassName+'</h3><p>The page you requested could '+ 'not be found - due to an error.</p><p>This may has '+ 'been caused by the following scenario:</p><ul><li>'+ '<p>'+E.Message+'.</p></li></ul>'+ '<p>Apology for the inconvenience.</p></td> </tr>'+ '</table></body></html>'); end; finally theResponse.Free; theHeader := nil; NetHTTPClient1.Free; end; end else begin Result := PChar('<html><head><title>400 Error</title></head>'+ '<body bgcolor="#ffffff" leftmargin="0" topmargin="0" '+ 'marginwidth="0" marginheight="0"><table width="75%" '+ 'border="0" cellpadding="50" cellspacing="0"><tr>'+ '<td><h3>Bad Request</h3><p>The page you requested could '+ 'not be found - due to a 400 error.</p><p>This may have '+ 'been caused by the following scenarios:</p><ul><li>'+ '<p>You may have typed the address wrong</p></li><li>'+ '<p> We may have moved the page, created a bad link or '+ 'be experiencing temporary problems.</p></li></ul>'+ '<p>Apology for the inconvenience.</p></td> </tr>'+ '</table></body></html>'); end; end; function PostHTTP(theURL,PostData,theHeaders, theOptions: PChar): PChar; {$ifdef win32} Stdcall;{$endif} Export; var I: Integer; begin if theURL <> '' then begin try theHeader := TNetHeaders.Create(); theResponse := TStream.Create; NetHTTPClient1 := TNetHTTPClient.Create(nil); NetHTTPClient1.AcceptCharSet := 'UTF-8'; NetHTTPClient1.UserAgent := BrowserAgent[Random(2)]; try if theHeaders <> '' then begin HeaderArray := Split('|',String(theHeaders)); for I := 0 to HeaderArray.Count - 1 do begin theHeader[I].Value := HeaderArray[I]; end; end; if UpperCase(theOptions) = 'YES' then begin DummyValue := PChar(NetHTTPClient1.Options(String(theURL),theResponse,theHeader).StatusText); end; Result := PChar(NetHTTPClient1.Post(String(theURL),String(PostData),theResponse, theHeader).ContentAsString()); except on E : Exception do Result := PChar('<html><head><title>Error page - '+E.ClassName+'</title></head>'+ '<body bgcolor="#ffffff" leftmargin="0" topmargin="0" '+ 'marginwidth="0" marginheight="0"><table width="75%" '+ 'border="0" cellpadding="50" cellspacing="0"><tr>'+ '<td><h3>Request error - '+E.ClassName+'</h3><p>The page you requested could '+ 'not be found - due to an error.</p><p>This may has '+ 'been caused by the following scenario:</p><ul><li>'+ '<p>'+E.Message+'.</p></li></ul>'+ '<p>Apology for the inconvenience.</p></td> </tr>'+ '</table></body></html>'); end; finally theResponse.Free; theHeader := nil; NetHTTPClient1.Free; end; end else begin Result := PChar('<html><head><title>400 Error</title></head>'+ '<body bgcolor="#ffffff" leftmargin="0" topmargin="0" '+ 'marginwidth="0" marginheight="0"><table width="75%" '+ 'border="0" cellpadding="50" cellspacing="0"><tr>'+ '<td><h3>Bad Request</h3><p>The page you requested could '+ 'not be found - due to a 400 error.</p><p>This may have '+ 'been caused by the following scenarios:</p><ul><li>'+ '<p>You may have typed the address wrong</p></li><li>'+ '<p> We may have moved the page, created a bad link or '+ 'be experiencing temporary problems.</p></li></ul>'+ '<p>Apology for the inconvenience.</p></td> </tr>'+ '</table></body></html>'); end; end; exports GetHTTP, PostHTTP; begin end. and this EXE to call unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm2 = class(TForm) WEBResult: TMemo; HTTPURL: TEdit; Button1: TButton; PostData: TMemo; RequestHeader: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; function GetHT4TP(theURL,theHeaders, theOptions: PChar): PChar; external 'WEB.dll'; function PostHTTP(theURL,PostData,theHeaders, theOptions: PChar): PChar; external 'WEB.dll'; implementation {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); begin WEBResult.Text := String(GetHTTP(PChar(HTTPURL.Text),PChar(RequestHeader.Text), 'No')); end; procedure TForm2.Button2Click(Sender: TObject); begin WEBResult.Text := String(PostHTTP(PChar(HTTPURL.Text),PChar(PostData.Text),PChar(RequestHeader.Text), 'No')); end; end. Both are compiled by Delphi 10.4 CE on Windows 10 Pro 22H2 x64 without any errors, however, when the EXE is executed it shows this error : "The program couldn't start correctly (0xc0000142). Click OK to close the program" I guess I have missed something and can't seem to find it ... fresh eyes would be appreciated enormously !!! EDIT: I found out that I just had to remove ShareMem from uses clause and GetHTTP function works as expected, however, PostHTTP shows this error: "Access violation at address 0000000000D8F4B4 in module 'Library.dll'. Read of address 0000000000000008"
-
Problem solved ..... just had to switch to PChar instead of string........... and add {$ifdef win32} Stdcall;{$endif} Export; to the function in the DLL
-
defined like this: function GetExtWEB2(URLstr: String): String; stdcall; external 'HTTP2.dll'; and called like this from the main program: Result := GetExtWEB2(URL);
-
library HTTP2; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses ShareMem , System.SysUtils, System.Variants, System.Classes, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent; {$R *.res} function GetExtWEB2(theURL: String): String; var NetHTTPClient1: TNetHTTPClient; ResultStr: String; begin NetHTTPClient1 := TNetHTTPClient.Create(nil); NetHTTPClient1.AcceptCharSet := 'UTF-8'; NetHTTPClient1.UserAgent := 'MyHTTP2 Client'; try try ResultStr := NetHTTPClient1.Get(theURL).ContentAsString(); Result := ResultStr; except on E : Exception do Result := '{"message":"error","errorclass":"'+E.ClassName+'","errormsg":"'+E.Message+'"}'; end; finally NetHTTPClient1.Free; end; end; exports GetExtWEB2; end.
-
Tried that and still same result ....
-
If referring to BORLNDMM.DLL and so is ShareMem .. it is in place in the exe directory
-
I was trying out Delphi CE 10.4 on Win 10 x64 and made a little project with an app and a project with and DLL and discovered something which doesn't make sense to me... The HTTP protocol is HTTP/2.... the EXE project: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent, Vcl.StdCtrls; type TForm2 = class(TForm) NetHTTPClient1: TNetHTTPClient; Memo1: TMemo; Edit1: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} function GetExtWEB2(theURL: String) : String; begin Result := Form2.NetHTTPClient1.Get(theURL).ContentAsString(); end; procedure TForm2.Button1Click(Sender: TObject); begin Memo1.Text := GetExtWEB2(Edit1.Text); end; end. and the DLL project: library HTTP2; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils, System.Variants, System.Classes, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent; {$R *.res} function GetExtWEB2(theURL: String): String; var NetHTTPClient1: TNetHTTPClient; begin NetHTTPClient1 := TNetHTTPClient.Create(nil); NetHTTPClient1.AcceptCharSet := 'UTF-8'; NetHTTPClient1.UserAgent := 'MyHTTP2 Client'; try try Result := NetHTTPClient1.Get(theURL).ContentAsString(); except on E : Exception do Result := '{"message":"error","errorclass":"'+E.ClassName+'","errormsg":"'+E.Message+'"}'; end; finally NetHTTPClient1.Free; end; end; exports GetExtWEB2; end. the EXE project gives me this result: {"translations":[{"detected_source_language":"EN","text":"Jeg tester online-oversættelse"}]} the DLL gives me this result: External exception EEDFADE I wonder what I am doing wrong in the DLL and causes this mishap ?? Any help is appreciated and ....