0
votes

For my last project i was using many frames in my delphi application ,so i dicided to create dlls and put them inside the dlls(ALL created in Delphi)

i have gone through many websites and came up with the code that works but for that example i have to compile both apps and dlls with build with runtime packages which means i have to distribute the bpls also. and if dont check build with runtime packages error is coming

this is the code i found

in exe

procedure TForm1.Button1Click(Sender: TObject);
type
TGetTheFrame =Function( Owner: TComponent; TheParent: TWinControl ): TFrame; stdcall ;
 var
  GetTheFrame : TGetTheFrame;
begin
try
   GetTheFrame(application,TabSheet1).Free ;
except
end;
frm := GetTheFrame(application,TabSheet1) ;
dllHandle := LoadLibrary('project1.dll') ;
   if dllHandle <> 0 then
   begin
     GetTheFrame := GetProcAddress(dllHandle, 'GetTheFrame') ;
  frm := GetTheFrame(application,TabSheet1)   //call the function
    {   ShowMessage('error function not found') ;
     FreeLibrary(dllHandle) ; }
   end
   else
   begin
     ShowMessage('xxxx.dll not found / not loaded') ;
   end

in dll

Function  GetTheFrame( Owner: TComponent; TheParent: TWinControl ): TFrame; stdcall;
Begin
 Result := TFrame2.Create( Owner );

 Result.Parent := TheParent;
End;

thats all but i want this code to work without runtime packages

1
but i am sure code is good because it worked with runtimw=e packagesVibeeshanRC
What's the purpose of that first GetTheFrame call? If it was meant to do anything other than randomly trash your memory, then you're using it wrong. The compiler should warn that you're using an uninitialized variable there.Rob Kennedy
You've misunderstood. That first call is wrong for two reasons (and not just sometimes, but always). GetTheFrame is a local variable, so upon entry to Button1Click, it will not have a valid value. In particular, it will not refer to the DLL function. Even if it did refer to a valid function, it's not accomplishing anything. The only memory it would free is the very same memory that it just allocated. It's a pointless call because it's not freeing anything that wasn't allocated previously.Rob Kennedy
And furthermore, you're unloading the DLL right after you create an object. You mustn't do that. The object you created still needs the DLL to reside in memory, or else the object's code will go away. The object's memory also won't be managed anymore because it was managed by the DLL's copy of the memory manager, which has of course disappeared.Rob Kennedy
What do you think you are you acheiving by using DLL's in the first place? You have to distribute the dll's anyways, you might as well include the frames in the exe itself and save yourself the hassle.GrandmasterB

1 Answers

7
votes

Too bad. That code won't work without run-time packages. (And with run-time packages, you should use LoadPackage instead of LoadLibrary.)

Without packages, each module of your program (the EXE and each DLL) has its own copy of the definition of all the standard classes, including TFrame, TWinControl, and even TObject. A TWinControl class from the EXE doesn't look like a TWinControl to the DLL.

Since you're sharing classes between modules, you need to make sure they all have the same definitions of those classes, and run-time packages is how you do that.

If you really won't use run-time packages, then you need to change the interface of your DLL so it doesn't share any Delphi object types. Instead of the TWinControl parent, pass the control's Handle property, or any other HWnd value to serve as the parent window. The DLL code will not be able to assume that there is a Delphi object for the parent anymore, and the EXE will not be able to assume that the control it receives is a Delphi object; they will be restricted to using the Windows API to manipulate window handles and send messages.