AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Delphi-PRAXiS - Lounge Delphi-News aus aller Welt "Invalid EurekaLog configuration found" error

"Invalid EurekaLog configuration found" error

Ein Thema von DP News-Robot · begonnen am 13. Mai 2025
 
Benutzerbild von DP News-Robot
DP News-Robot

Registriert seit: 4. Jun 2010
15.826 Beiträge
 
#1

"Invalid EurekaLog configuration found" error

  Alt Heute, 13:40
Users of recent EurekaLog versions could receive the "Invalid EurekaLog configuration found" error message when they run their EurekaLog-enabled applications. The message looks like this:
Invalid EurekaLog configuration found.Exception from the following module:full-file-name-to-your-EXE-or-DLLwas catched in the following module:full-file-name-to-your-DLL-or-EXEBoth modules have EurekaLog enabled, but EurekaLog code is not shared.This is essentially the same error as:- "Can''t assign a TFont to a TFont";- "Invalid class typecast";- reInvalidCast;- "Run-time error 10".etc.Possible solutions:- Do not allow exceptions from one module escape into another (recommended)- Compile DLLs with Lightweight DLL profile, so your DLL will not have EurekaLog's code- Compile EXE and DLL with run-time packages, so EXE and DLL will share EurekaLog's codeSee our help for more information:https://www.eurekalog.com/help/eurek..._eurekalog.php


What this check is

Previous versions of EurekaLog did not have this check, so users could configure their projects incorrectly and then contact us asking why various bad things happens or why EurekaLog behave incorrectly. That is why recent versions of EurekaLog perform this check explicitly to let users know they are doing something wrong.

The check is triggered when EurekaLog catches exception, which has EurekaLog information assigned, but this EurekaLog information does not come from EurekaLog itself! In other word, it comes from (a different) EurekaLog in a different module (EXE or DLL).


What the problem is

We think that the message is pretty self-explanatory, but here is another example (without using EuerkaLog): suppose you have a function in DLL like this:function CreateForm: TForm; stdcall; export;begin Result := TMyForm.Create(nil);end;which is being called from EXE. As you should know, EXE and DLL both have each own code of VCL (by default). Which means there are DLL.TForm and EXE.TForm - two different things. So essentially you create "something" (object) in DLL and pass it back to EXE, which expects it to be EXE.TForm - but it is not: it is DLL.TForm.

The same thing is true for the reverse case: when EXE pass objects into DLL. For example, one may choose to pass EXE's Application or MainForm to DLL in order for DLL to display owned/child forms.

Such code is a bad design. You should never write such code.

We should note: such code can work - by coincedence: when all of the below conditions are true:
  1. If both DLL and EXE are compiled with exactly the same version of VCL (or another code which implements passed objects) - so the object's layout in memory is the same for EXE and DLL;
  2. If the caller does not check for the class explicitly (not using InheritsFrom, as operator, is operator, etc) on returned object and all of its properties (and properties of properties).
  3. When at least one (any) condition is met:
    • If the caller does not modify dynamic properties (strings, dynamic arrays, interfaces, etc.) of the returned object and does not call non-virtual object's methods that could do so. Basically, no (re)allocating memory in returned object.
    • EXE and DLL share memory manager.
Did you notice? This list is basically saying that this code is WRONG:
procedure FuncInDLL; stdcall;begin // your codeend;Why? Well, imagine an exception happens in this function. What is exception in Delphi? Well, it is an object derived from the Exception class. In other words, an object (exception) created in DLL will be passed to EXE.

As you may suspect: most (?) Delphi DLLs are written in this way. And authors of these DLLs are saying: "this code works".

What they don't realize is that this code "works" by coincedence. For example, if a DLL will be loaded in EXE compiled with a different IDE version, memory layout of the Exception class may be different, so either EXE will crash trying to access properties of exception or it will corrupt exception object on write - leading to access violation and/or memory leaks. Another problem if EXE will decide to do something like:
try FuncInDLL;except // This filter will not work, // as the DLL.Exception class will not match the EXE.Exception class on E: Exception do begin ShowMessage(E.Message); Exit; end; end;or:
try FuncInDLL;except // This will not work, // as EXE will manipulate memory for DLL Exception(ExceptObj).Message := 'Error in My DLL: ' + Exception(ExceptObj).Message; raise;end;
So, when you have code like:
procedure FuncInDLL; stdcall;begin // your codeend;and it "works", and then you add EurekaLog to your DLL and EXE.

EurekaLog creates objects containing collected information about exception (the TEurekaExceptionInfo class from the EException unit) and associate these exception info objects with exceptions. So if you pass exception between DLL and EXE - you also pass EurekaLog's exception info object between DLL and EXE. And these objects are way more complex than exception objects, and EurekaLog do way more things that your code do with exceptions. So EurekaLog's code will certainly check exception info object's class (to see if an exception has associated exception's info) as well as modify exception info object. Which means: access violation, leaks, incorrect behaviour.


Solutions

The exact solution depends on what kind of DLL you are developing:

"Pure DLL"

If you are developing a pure DLL - that is: a DLL which can be loaded by any application - then the solution is to never let exceptions escape your DLL. In other words, each and every exported function must have an except block. An except block can be explicit like this:
function FuncInDLL: BOOL; stdcall;begin try // your code Result := True; // only as an example except // handle exception here Result := False; // only as an example end;end;or it can be implicit like this:
procedure FuncInDLL; safecall; // notice "safecall"begin // your codeend; In either way, any DLL exception will be handled in the DLL itself and will not leave the DLL. The caller (EXE) will never receive exceptions from DLL, but rather some "failure" flag.

Read this article for more details.

"Delphi DLL"

If you are developing a Delphi DLL which can be used in Delphi applications only - then the solution is to use packages (BPLs).

One option is to convert your DLL to a BPL package. Another option is to compile EXE and DLL with BPL packages. The end result will be the same: both DLL and EXE will share common code and memory manager, therefore eliminating the problem.

So what you should do is to enable the "Link with runtime packages" option in your project's settings and ensure at least the rtl, vcl and EurekaLogCore packages are listed in the "Runtime packages" list. Using the rtl package will ensure using shared memory manager (so you can remove a dedicated shared memory manager from your DLL/EXE if you set up it previosly), while using the EurekaLogCore package will ensure sharing EurekaLog's code between EXE and DLL.

Important note:
Since your DLL will call EurekaLog from the EurekaLogCore package, the EurekaLogCore package will not know who is calling it (EXE or DLL). Therefore, it does not know where it should look for EurekaLog's options. That is why the EurekaLogCore package will always load EurekaLog's options (settings) from EXE. EurekaLog's settings from your DLL will be ignored.

This is kinda obvious, if you think about it: using the EurekaLogCore package means there is only one instance of EurekaLog in your process, so you can't have two EurekaLog's options (from EXE and DLL) at the same time.

In other words, configure EurekaLog in EXE. For DLL: you can configure EurekaLog as a "package" (if you don't call EurekaLog's code from your DLL) or as "Standalone DLL" (if you do call EurekaLog's code from your DLL).
"Application DLL"

If you are developing a Delphi DLL which will be used in your specific application only - then the solution is to configure your DLL as lightweight DLL.

Note: the solution from the "Delphi DLL" above will also work, but if you don't want to compile with packages (while you definitely should), using "Lightweight DLL" configuration is a possible alternative.

When you configure your DLL as a "Lightweight DLL": EurekaLog's code will not be included in your DLL. Instead: your DLL will make a calls to EurekaLog in your main EXE. Therefore, your process will have only one instance of EurekaLog (in your EXE), while your DLLs will call into EurekaLog from EXE.


Conclusion

We understand that this error message could be frustrated for users which were using previous versions of EurekaLog. Especially considering the message does not appear at design-time, and it does not appear on startup at run-time, but it rather appears when a specific exception is thrown, which can be detected a lot later.

However, you should realize the error dialog is shown to clearly indicate an issue in your application rather than letting the application silently run further and produce hard to diagnose issues later.

We offer possible solutions, among simplest of which is reconfiguring EurekaLog in DLL as "Lightweigh DLL" - without touching your existing EXE/DLL code.

P.S. Read more about using EurekaLog in DLLs.
P.P.S. Read more about writing pure DLLs in Delphi.
P.P.P.S. We should note using a dedicated shared memory manager is a hack (crutch) from Delphi 2. New code should never use it. Using BPL packages (when developing a Delphi DLL) or following the "whoever allocates memory - frees it" rule (when developing a pure DLL) is a correct way.

Weiterlesen...
  Mit Zitat antworten Zitat
 

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz