Unload CEF without shutting down the program?

Post Reply
parlavamba
Posts: 5
Joined: Tue May 19, 2020 12:19 pm

Unload CEF without shutting down the program?

Post by parlavamba » Tue May 19, 2020 12:58 pm

Hi,
I am trying to use CEF4Delphi 81.2.16+chromium-81.0.4044.92 in my DLL with modal form and have encountered a problem.
I need to load the SEF at the beginning of working with the DLL and unload the CEF before unloading my DLL. Loading and unloading takes place inside my DLL.
I added

Code: Select all

MustFreeLibrary := True
, but CEF is not unloaded, and AV occurs when the form is run again, since

Code: Select all

GlobalCEFApp.StartMainProcess
cannot start.

I did an experiment in the DLLBrowser demo - added

Code: Select all

GlobalCEFApp.MustFreeLibrary := True
before

Code: Select all

GlobalCEFApp.StartMainProcess
, but when I run "3. Finalize", I get the AV a few seconds after unloading the CEF.

How can I load and unload CEF correctly without shutting down the program?
Please help me.

User avatar
salvadordf
Posts: 2337
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Unload CEF without shutting down the program?

Post by salvadordf » Wed May 20, 2020 8:27 am

Hi,

There are a few of things you have to consider when using a DLL with CEF :
  • CEF needs to be initialized and finalized outside the DLL's initialization and finalization sections.
  • CEF can only be initialized once per process but there are some exceptions : https://www.briskbard.com/forum/viewtopic.php?f=8&t=1315

If the code in the DLLBrowser demo works for your application I would recommend that you copy it.

parlavamba
Posts: 5
Joined: Tue May 19, 2020 12:19 pm

Re: Unload CEF without shutting down the program?

Post by parlavamba » Wed May 20, 2020 10:00 am

Hi, thank you for your answer.

I'll try to explain in more detail:
There is an application that the DLLs connect to. But there is no source code for this app, it is closed.
I can only work with a DLL, and I need to use chromium in my DLL, that is, both initialize and release chromium inside the DLL.
My DLL can run from this application several times, so I need to release the CEF each time and initialize it again without closing the application.

Is it impossible to do this?
I just need to completely unload the CEF so that the next time I run my DLL from the app, it can be re-initialized.

parlavamba
Posts: 5
Joined: Tue May 19, 2020 12:19 pm

Re: Unload CEF without shutting down the program?

Post by parlavamba » Wed May 20, 2020 10:11 am

Maybe there is some way to kill all the remaining CEF threads to release "libcef.dll" ?
Then "GlobalCEFApp.StartMainProcess" can be executed again without errors.

parlavamba
Posts: 5
Joined: Tue May 19, 2020 12:19 pm

Re: Unload CEF without shutting down the program?

Post by parlavamba » Wed May 20, 2020 10:23 am

This is how the DLL is called, the application calls the Delivery Address function:

Code: Select all

procedure DeliveryAddress(AOwner: TComponent; ACallBack: TDLLCallBack);
begin
  try
    CreateGlobalCEFApp;
    DM := TDM.CreateDM(nil, ACallBack);
    DeliveryAddressForm := TDeliveryAddressForm.Create(nil);
    try
      DeliveryAddressForm.ShowModal;
    finally
      DeliveryAddressForm.Free;
      DM.Free;
      Application.Handle := 0;
      DestroyGlobalCEFApp;
    end;
  except
    on E:Exception do
      MessageBox(Application.Handle, PWideChar(E.ClassName + ' - ' + E.Message), 'Error!', 0);
  end;
end;

procedure CreateGlobalCEFApp;
var
  LLibPath: string;
begin
  LLibPath := ExtractFilePath(paramstr(0)) + 'Lib\';
  GlobalCEFApp := TCefApplication.Create;
  GlobalCEFApp.FrameworkDirPath := LLibPath;
  GlobalCEFApp.ResourcesDirPath := LLibPath;
  GlobalCEFApp.Cache := LLibPath + 'cache';
  GlobalCEFApp.UserDataPath := LLibPath + 'userData';
  GlobalCEFApp.LocalesDirPath := LLibPath + 'locales';
  GlobalCEFApp.BrowserSubprocessPath := LLibPath + 'SubProcess.exe';
  GlobalCEFApp.MustFreeLibrary := True;
  GlobalCEFApp.StartMainProcess;
end;
After closing the form and starting again, an AV error appears on "GlobalCEFApp.StartMainProcess" with the message "libceff.dll busy with another process."

User avatar
salvadordf
Posts: 2337
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Unload CEF without shutting down the program?

Post by salvadordf » Wed May 20, 2020 10:24 am

As far as I know, CEF doesn't allow you to initialize it several times in the same process. This is a CEF feature and there's no workaround.

I thought that was an unbreakable CEF rule until I saw the exception I commented earlier but I would try to use CEF as suggested by the CEF maintainer.

However, if you make some tests and find more exceptions to this rule, please let us know! :D

If you follow the official recommendations then you would have to create a separate application with the CEF browser. Then use some form of Inter-process communication (IPC) to send and receive commands and information from your DLL to the new application like this :

Code: Select all

Main app <---> your DLL <--(IPC)--> The new CEF browser App
This way you would launch and close the new CEF browser app each time your DLL is loaded/unloaded.

parlavamba
Posts: 5
Joined: Tue May 19, 2020 12:19 pm

Re: Unload CEF without shutting down the program?

Post by parlavamba » Wed May 20, 2020 10:32 am

This is very sad :( .
Thank you for your help, kind man.

Post Reply