- Which units used: as mentioned earlier today: LazLogger, LazLoggerBase (for: GetExistingDebugLogger), LazClasses (for: TRefCountedObject).
(i see, it would be better to keep the pieces together at one place, so below).
- "Putting an object reference into the function pointer => that should crash"
But isn't it the same if one does : "Result := TLazLoggerFile.Create" and Result is type TRefCountedObject
or one does : var xyz: TRefCountedObject; and then xyz := TLazLoggerFile.Create ?
The question is only: what can we do with such instance of a reference counter, can we operate on it (for me it sounds confusing, and i can only guess).
At least: it doesn't crash (and the object hadn't been nil).
- I had also tried with "DebugLogger", but had not success.
But now: i tried to show all steps and interims results more detailed. And, doing so, i got a new situation.
interface
uses ....,
LazLogger.
LazLoggerBase, // needed for GetExistingDebugLogger
LazClasses; // needed for TRefCountedObject
procedure TXYZDockingForm.FormCreate(Sender: TObject);
var ....., LazDebugLoggerCreator: TRefCountedObject;
begin
// -- Test 1
if DebugLogger = nil then
OutputDebugString(pchar('DebugLogger is nil'))
// Note: OutputDebugString here only as temporary display instrument:
else
begin
OutputDebugString(pchar('DebugLogger LogName = ' + TLazLoggerFile(DebugLogger).LogName )); // "DebugLogger.LogName" would be not compileable
TLazLoggerFile(DebugLogger).LogName := 'D:\__Temp\yy\___aLogfile.txt';
OutputDebugString(pchar('DebugLogger new assigned LogName = ' + TLazLoggerFile(DebugLogger).LogName )); // "DebugLogger.LogName" would be not compileable
end;
DebugLn(' ----- Welcome logfile !');
// -- Or Test 2
LazDebugLoggerCreator := TLazLoggerFile.Create;
if LazDebugLoggerCreator = nil then
OutputDebugString(pchar('LazDebugLoggerCreator is nil'))
else
if TLazLoggerFile(LazDebugLoggerCreator) = nil then
OutputDebugString(pchar('TLazLoggerFile(LazDebugLoggerCreator) is nil'))
else
begin
// This was only temporarely an additional test:
TLazLoggerFile(LazDebugLoggerCreator).Assign(GetExistingDebugLogger); // optional / if you call only once there should be none to copy any setting from
OutputDebugString(pchar(' Assigned GetExistingDebugLogger; log name = ' + TLazLoggerFile(LazDebugLoggerCreator).LogName));
TLazLoggerFile(LazDebugLoggerCreator).LogName := 'D:\__Temp\yy\___aLogfile.txt';
OutputDebugString(pchar(' Assigned new log name: ' + TLazLoggerFile(LazDebugLoggerCreator).LogName));
end;
DebugLn(' ----- Welcome logfile !');
Attached as images the individual output results (i did either Test1 or Test2, not both together).
One can see: both appear to behave very unsuspicious (no crash, no nil; assignment appeared to be good).
Test2 (that was the previous approach) did Not result in a logfile.
Test1 - using the existing "DebugLogger" - finally generated the desired log file, and it said: ----- Welcome logfile !
That means, success so far: useable in the DLL's main unit / form at least seems to be:
if DebugLogger <> nil then
TLazLoggerFile(DebugLogger).LogName := <desired_path_and_name>;
This can be applied to other forms within the dll app too (uses LauLogger here and doing the same assignment as above. DebugLn then will append to the same log file).
So far, so very good! We can defiine the logfile name (in a DLL ->) there, were a command line parameter is not applicable.
The second and last chaptor will be: how to make this operational for not self-written units, eg. toolbutton.inc, toolbar.inc etc.
(First i'll try to transfer it to the core pas file of the plugin / initialization section, and then see, how far this matters.
(Actually a DebugLn in eg. treeview.inc is compilable, but results in nothing. Probably LazLoggerDummy is at work. Tried to compile with custom option -dDEBUG, but that, actually, caused other issues; couldn't compile; range check errors. Need to investigate.)