DanishMale 0 Posted April 3, 2023 (edited) 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 .... Edited April 3, 2023 by DanishMale Share this post Link to post
Der schöne Günther 316 Posted April 3, 2023 You probably might want to read the "Important note about DLL memory management" you just posted. 1 Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 maybe use a temp string-var to receive and pass to restult, instead obj-NetHttp? Share this post Link to post
DanishMale 0 Posted April 3, 2023 (edited) 7 minutes ago, Der schöne Günther said: You probably might want to read the "Important note about DLL memory management" you just posted. If referring to BORLNDMM.DLL and so is ShareMem .. it is in place in the exe directory Edited April 3, 2023 by DanishMale Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 no... here uses ShareMem, .... ; Share this post Link to post
DanishMale 0 Posted April 3, 2023 7 minutes ago, programmerdelphi2k said: maybe use a temp string-var to receive and pass to restult, instead obj-NetHttp? Tried that and still same result .... Share this post Link to post
DanishMale 0 Posted April 3, 2023 4 minutes ago, programmerdelphi2k said: no... here uses ShareMem, .... ; 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. Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 look this: https://en.delphipraxis.net/topic/8132-using-writeln-in-dll/?do=findComment&comment=68661 Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 Quote var LogFn: procedure; hLib: THandle; begin try hlib := LoadLibrary('Lib.dll'); @LogFn := GetProcAddress(hLib, 'Log'); LogFn(); LogFn: function GetExtWEB2(theURL: String): String; Share this post Link to post
DanishMale 0 Posted April 3, 2023 8 minutes ago, programmerdelphi2k said: how you call this dll? defined like this: function GetExtWEB2(URLstr: String): String; stdcall; external 'HTTP2.dll'; and called like this from the main program: Result := GetExtWEB2(URL); Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 did try debug the DLL to see if any error happens there? Share this post Link to post
DanishMale 0 Posted April 3, 2023 (edited) Problem solved ..... just had to switch to PChar instead of string........... and add {$ifdef win32} Stdcall;{$endif} Export; to the function in the DLL Edited April 4, 2023 by DanishMale Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 (edited) hi @DanishMale you forgot the STDCALL in DLL exportation: Edited April 3, 2023 by programmerdelphi2k Share this post Link to post
programmerdelphi2k 237 Posted April 3, 2023 (edited) ShameMem in DLL / Project (view-source Project1) // DLL function MyHttp2(AValue: string): string; // stdcall; begin result := 'hello world'; end; exports MyHttp2; var Form1: TForm1; // function MyHttp2(AValue: string): string; stdcall; external 'MyDLL.DLL'; function MyHttp2(AValue: string): string; external 'MyDLL.DLL'; implementation {$R *.dfm} procedure TForm1.BtnLoadLibraryDLLClick(Sender: TObject); var MyF: function(AValue: string): string; H : THandle; begin H := LoadLibrary(PWideChar('MyDLL.DLL')); // dynamic call // if H > 0 then try MyF := GetProcAddress(H, PWideChar('MyHttp2')); // if (@MyF <> nil) then Caption := MyF('hi'); finally FreeLibrary(H); end; end; procedure TForm1.BtnCallDLLStaticBindedClick(Sender: TObject); begin Caption := MyHttp2('hi'); // static call end; Edited April 3, 2023 by programmerdelphi2k Share this post Link to post