|
Registriert seit: 4. Jun 2010 15.826 Beiträge |
#1
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: ![]() ![]() 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:
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 ![]() "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."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. ![]() P.P.S. ![]() P.P.P.S. We should note using a dedicated shared memory manager is a hack (crutch) from Delphi 2. ![]() ![]() |
![]() |
Themen-Optionen | Thema durchsuchen |
Ansicht | |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
LinkBack |
![]() |
![]() |