Jump to content
DanishMale

NetHTTPClient

Recommended Posts

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 by DanishMale

Share this post


Link to post
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 by DanishMale

Share this post


Link to post
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 .... :classic_blink:

Share this post


Link to post
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
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
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

Problem solved ..... just had to switch to PChar instead of string...........:classic_blush::classic_blush::classic_blush::classic_blush::classic_blush::classic_blush::classic_blush::classic_blush::classic_blush:

 

and add {$ifdef win32} Stdcall;{$endif} Export;  to the function in the DLL

Edited by DanishMale

Share this post


Link to post

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 by programmerdelphi2k

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×