-3

I have created a DLL in Delphi 10.3.3 and compiled it (as 32-bit):

library TestDLL;

uses
  Vcl.ExtCtrls,
  Vcl.Graphics,
  System.SysUtils,
  System.Classes;

{$R *.res}

procedure ColorPanel(APanel: TPanel);
begin
  APanel.Color := clRed;
end;

exports
  ColorPanel;

begin
end.

Then in Delphi 10.3.3 I created a VCL application to host the DLL:

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TForm3 = class(TForm)
    pnlTest: TPanel;
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure ColorPanel(APanel: TPanel);  external 'TestDLL.dll';

procedure TForm3.btnTestClick(Sender: TObject);
begin
  ColorPanel(pnlTest);
end;

end.

This is the form file 'Main.dfm':

object Form3: TForm3
  Left = 0
  Top = 0
  Caption = 'Form3'
  ClientHeight = 217
  ClientWidth = 359
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  PixelsPerInch = 120
  TextHeight = 16
  object pnlTest: TPanel
    Left = 0
    Top = 0
    Width = 153
    Height = 217
    Align = alLeft
    Caption = 'pnlTest'
    TabOrder = 0
  end
  object btnTest: TButton
    Left = 208
    Top = 24
    Width = 75
    Height = 25
    Caption = 'Test'
    TabOrder = 1
    OnClick = btnTestClick
  end
end

And this is the project file 'TestDLL.dpr':

program DllHost;

uses
  Vcl.Forms,
  Main in 'Main.pas' {Form3};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm3, Form3);
  Application.Run;
end.

Clicking on the button should colorize the panel red.

Why does it not work and how can I make it work?

user1580348
  • 5,721
  • 4
  • 43
  • 105
  • 1
    This won't work. You need to use packages. – David Heffernan Jan 19 '20 at 21:09
  • Packages will not work because the host is a different Delphi version than the DLL. You can see from my code that the DLL works perfectly. Why you are always trying to sabotage me? – user1580348 Jan 19 '20 at 23:10
  • [DLL dos and don’ts](http://www.rvelthuis.de/articles/articles-dlls.html) from Rudy Velthuis: "Limit your types to the types the C language has, or to structs/records of these types. In other words, do not export data types that are specific to a certain language, like C++ templates, objects (eg. std::string) or Delphi objects, AnsiStrings, UnicodeStrings, etc." – Delphi Coder Jan 20 '20 at 06:18
  • 4
    If you have different delphi versions, then your code can only work by accident. You will be executing code from one version of the VCL on an object from a different version of the dll. Even with the same delphi versions it doesn't work because you have two different instances of the VCL. Whatever the problem is, thus isn't the solution. – David Heffernan Jan 20 '20 at 07:10
  • 2
    user1580348: In your Q, you wrote "Why does it not work and how can I make it work?" but in your reply to @David's comment, you wrote "You can see from my code that the DLL works perfectly." This latter comment is not only strange, it seems to be contradicted by your comment in your Q. – Andreas Rejbrand Jan 20 '20 at 07:57
  • 3
    Also, in your Q, you wrote that the DLL and client application both are built using Delphi 10.3.3, but in your comment you wrote "the host is a different Delphi version than the DLL", which I also find a bit strange. – Andreas Rejbrand Jan 20 '20 at 08:00

1 Answers1

1

Please also set ParentBackground of pnlTest to false either from code or in the dfm.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • Thanks. Do I also have to free memory when closing the program? – user1580348 Jan 19 '20 at 19:59
  • 1
    Nope. This problem isn't due to the calls over to a DLL. So long as you don't call the constructor from outside of the DLL and the destructor within, or vice versa, you're fine. (Actually if both EXE and DLL use Delphi's memory manager, you're still fine.) But strange circumstances may give strange results, when in doubt use a memory leak detector. – Stijn Sanders Jan 19 '20 at 20:06
  • 6
    Using objects without Bpl is a really bad idea. May be it will work in a simple case, but then you are lucky. Do not do this. Use simple Wrappers or Interfaces – Fritzw Jan 20 '20 at 08:16