Recent

Author Topic: Failed to access library variable  (Read 1605 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 7622
Re: Failed to access library variable
« Reply #15 on: August 07, 2024, 10:37:19 am »
You'll see that to initialize the exported  module  record, the library's main  begin / end.  block is used (as @PascalDragon suggested).

And as one of the core developers, his suggestions should not be dismissed casually.

So the bottom line is that an Apache module (i.e. a library as distinct from a CGI binary etc.) needs a variable called "module" with all fields pre-initialised before it's loaded.

That's a clear case of needing to be done in the library's main block.

To summarise: the issue is not one of failing to access the library variable, but the variable not having been initialised at the point it is accessed.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

mikerabat

  • New Member
  • *
  • Posts: 49
Re: Failed to access library variable
« Reply #16 on: August 07, 2024, 11:20:11 am »
Quote
To summarise: the issue is not one of failing to access the library variable, but the variable not having been initialised at the point it is accessed.

Actually it's failing to access the variable within the library. The linker complains at any point - even if you would export a function that actually initializes the variable (aka not in the begin end of the shared module code).

cdbc

  • Hero Member
  • *****
  • Posts: 1513
    • http://www.cdbc.dk
Re: Failed to access library variable
« Reply #17 on: August 07, 2024, 11:31:42 am »
Hi
How about creating a pointer to your exported variable, in your library and then access this pointer in the begin .. end. block to initialize?!?
Like so:
Code: Pascal  [Select][+][-]
  1. Code: Pascal  [Select][+]
  2. // File: test.pas
  3. library test_lib;
  4.  
  5. {$mode objfpc}
  6. {$packrecords C}
  7.  
  8. type
  9.   PTestRec = ^TTestRec;
  10.   TTestRec = record
  11.     idx1: Integer;
  12.     idx2: Integer;
  13.   end;
  14.  
  15. var
  16.   idxData: TTestRec; cvar; export;
  17.  
  18. procedure InitData(prData: pointer); cdecl;
  19. begin
  20.   PTestRec(prData)^.idx1 := i1;
  21.   PTestRec(prData)^.idx2 := i2;
  22. end;
  23.  
  24. exports idxData;
  25.  
  26. begin
  27.   InitData(@idxData);
  28. end.
I dunno, just might work...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

mikerabat

  • New Member
  • *
  • Posts: 49
Re: Failed to access library variable
« Reply #18 on: August 07, 2024, 11:50:39 am »
Thanks for the suggestion cdbc...
I tried that already with no success. Hence my idea to "load" the same library via dlopen and get a pointer to the variable
with dlsym but of course that's kinda of a recursion that does not do the trick...

I don't know why the linker actually complains here anyway... and only on ARM it turned out.

MarkMLl

  • Hero Member
  • *****
  • Posts: 7622
Re: Failed to access library variable
« Reply #19 on: August 07, 2024, 12:05:49 pm »
Right. I don't have a running RPi at the moment, which rules me out for practical experimentation.

Quote
CodeTyphon IDE. Additional compiler options -fPIC -Xc

Try it using either Lazarus or FPC with a makefile or properly-described command line. If you still have problems post the exported ("published") Lazarus project here, and then hands-off to hopefully gave somebody a chance to look at it.

I've definitely had separately-linked code (i.e. .so etc.) running on an RPi before now, but looking at some of my stuff: because of the way I generate it (from a .inc describing the interface using a utility I've not published) the way I've done it is to have

* A concise main unit declaring appropriate exports.

* The main unit imports what it needs from other units, which initialise etc. stuff without problems.

hence

Code: Pascal  [Select][+][-]
  1. (* FPC 2.6.4 on Linux or Solaris FPC 2.6.4 on Linux or Solaris FPC 2.6.4 on Lin *)
  2.  
  3. library Analyzer_Vcd;
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7. uses
  8.   {$IFDEF UNIX}
  9.   cthreads,     (* <================    THIS IS REQUIRED!!!!!   =============== *)
  10.   {$ENDIF}
  11.   Classes, Analyzer_VcdCode;
  12.  
  13. { #todo -oMarkMLl -cLA :  Issue with constant/variable export here. }
  14.  
  15. exports
  16.   MagicNumber, State, Trigger, Stop, Rearm, Running;
  17.  
  18. end.
  19.  

with all the work done in the Analyzer_VcdCode unit.

Note that TODO I've got in there, from experience on x86_64 Debian Linux (i.e. I'd expect the linker etc. to be reasonably similar to what's on an RPi). However my recollection of that is that that was strictly related to *exporting* the MagicNumber variable rather than to initialising it.

However it looks as though you've hit something which is at least in part platform-specific, and it is by no means outside the bounds of possibility that the CodeTyphon project has applied unpublished patches to the way FPC interacts with the linker.

MarkMLl
« Last Edit: August 07, 2024, 12:15:03 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018