Recent

Author Topic: I lost in Code ...  (Read 2435 times)

paule32

  • Hero Member
  • *****
  • Posts: 563
  • One in all. But, not all in one.
Re: I lost in Code ...
« Reply #15 on: May 27, 2025, 08:49:08 am »
to see, what I making of I post there an older version of Forms.pas on the Project of @fibonacci and me.
@fibonacci contact me if you don't want that I open source this Part or partial code...

https://dpaste.com/DBG6VPRZC

Like you can see, I use two Parts:
- 1 times a EXPORT define, and
- 1 times a IMPORT define

all EXPORT's goes into the DLL
all IMPORT's goes into the EXE

The EXE calls act like stub Functions, where the stub Functions lay in the DLL.
Because FPC can not export CLASS or CLASS Methods - so I work with stub Functions.
We have a little bit payload because this circumstances - but I have not found a better way without changing the FPC Compiler sources.

Happy hacking ...
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: I lost in Code ...
« Reply #16 on: May 27, 2025, 09:11:07 am »
tBecause FPC can not export CLASS or CLASS Methods - so I work with stub Functions.
Well, tthat is not entirely true: this can be done because internally class instances are pointers. As long as the main program can see what that pointer means, you can instantiate classes from a dll. (You need a virtual abstract class on the program side).It is cumbersome, but can be done. And yes, that is hackery.
« Last Edit: May 27, 2025, 09:12:38 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cdbc

  • Hero Member
  • *****
  • Posts: 2249
    • http://www.cdbc.dk
Re: I lost in Code ...
« Reply #17 on: May 27, 2025, 09:12:33 am »
Hi
But paule32 you CAN EXPORT interfaces! Both COM & CORBA  8-)
If you use managed types e.g.: COM or strings & arrays you need to use a shared memory manager, otherwise CORBA interfaces work just as well with only the C-API, just NO managed types...
I use plugins this way "as a daily driver"  ;D
Regards Benny

eta: Thaddy beat me to it, 2 approaches with basically the same result...ish
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: I lost in Code ...
« Reply #18 on: May 27, 2025, 09:15:48 am »
Yes, basically using interfaces takes some of the hackery away, but class instances can be exported too.
I used interfaces (COM) together with my commm.pas (a shared memory manager that is COM Marshalled)
That would be early 2000's? The memory manager shoot-out?
« Last Edit: May 27, 2025, 09:18:49 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cdbc

  • Hero Member
  • *****
  • Posts: 2249
    • http://www.cdbc.dk
Re: I lost in Code ...
« Reply #19 on: May 27, 2025, 09:26:01 am »
Hi
Yup Thaddy it was, about that time, I was also fiddling with memory-managers, back then =^ ...Good times in Delphi  :D
@paule32: Here's a type-definition exported from a library, just to wet your appetite:
Code: Pascal  [Select][+][-]
  1. ///////////// IbcTaskThread / IbcSleepingThread ~ svc_taskthread.pas ////////////////
  2.  
  3.   { task definitions we can handle "In Our Sleep" :o) }
  4.   { TTaskEvent = procedure(Sender: TObject) of object;  we call this with provided data }
  5.   TTaskEvent = TNotifyEvent;
  6.   { extended TTaskEvent, sig: TTaskEventEx = procedure(anObj: TObject;aPtr: pointer) of object; }
  7.   TTaskEventEx = procedure(anObj: TObject;aPtr: pointer) of object;
  8.   { TTaskFunc = function(Parameter: pointer): ptrint; we call this with provided data }
  9.   TTaskFunc = TThreadFunc;
  10.   { TTaskProc = procedure(aParam: pointer); or we also call this with provided data }
  11.   TTaskProc = procedure(aParam: pointer);
  12.   { designated error }
  13.   ETaskThreadError = class(Exception);
  14.   { TTaskThread is our base worker-bee, purely abstract here, will get overridden }
  15.   TTaskThread = class(TThread)
  16.   protected
  17.     fCaller: ptrint; { owner handle }
  18.     fID: ptrint; { own id, given to us by the controller }
  19.     fSync: IReadWriteSync; { our internal locking object }
  20.     fTaskEvent: TTaskEvent;     ///=^
  21.     fTaskEventEx: TTaskEventEx; ///=^
  22.     fTaskFunc: TTaskFunc;       ///=^
  23.     fTaskProc: TTaskProc;       ///=^
  24.     function get_ID: ptrint; virtual; abstract;
  25.     function get_Sync: IReadWriteSync; virtual; abstract;
  26.     function get_TaskEvent: TTaskEvent; virtual; abstract;
  27.     function get_TaskEventEx: TTaskEventEx; virtual; abstract;
  28.     function get_TaskFunc: TTaskFunc; virtual; abstract;
  29.     function get_TaskProc: TTaskProc; virtual; abstract;  
  30.     procedure set_TaskEvent(aValue: TTaskEvent); virtual; abstract;
  31.     procedure set_TaskEventEx(aValue: TTaskEventEx); virtual; abstract;
  32.     procedure set_TaskFunc(aValue: TTaskFunc); virtual; abstract;
  33.     procedure set_TaskProc(aValue: TTaskProc); virtual; abstract;
  34.   public
  35.     property ID: ptrint read get_ID; { unprotected access }
  36.     property Sync: IReadWriteSync read get_Sync; { protection }      
  37.     property TaskEvent: TTaskEvent read get_TaskEvent write set_TaskEvent; { protected access }
  38.     property TaskEventEx: TTaskEventEx read get_TaskEventEx write set_TaskEventEx; { protected access }
  39.     property TaskFunc: TTaskFunc read get_TaskFunc write set_TaskFunc; { protected access }
  40.     property TaskProc: TTaskProc read get_TaskProc write set_TaskProc; { protected access }
  41.   end; { TTaskThread }
  42.   { PThreadCtrlRec carries support data for each thread }
  43.   PThreadCtrlRec = ^TThreadCtrlRec;
  44. {$Interfaces CORBA} { refcounting OFF }
  45.   { IbcTaskThread is the corba/raw thread service that sleeps :o) and can be woken up,
  46.     to perform a task; be it a taskprocedure, a taskfunction(ThreadFunc) or a:
  47.     e.g.: 'class procedure ExecWait(Arg: pointer); static;' declared in a TForm \o/
  48.     messages posted in MsgQueue by the thread:
  49.       3683 = ENTE(r)  -> entering execute;      2344 = BEGI(n)  -> starting task
  50.       3464 = FINI(sh) -> finished task;         3663 = DONE     -> going to sleep
  51.       7867 = STOP     -> exiting execute, going out of business
  52.       -1   = ERRO(r)  -> caught some kind of error, text is in message.
  53.     Creation: "params = [hOwner: ptrint; aMsgQ: IbcMessageQueue64; aDbgMsg: boolean]" or none.
  54.       if not if not PluginMgr.GetSvc('IbcTaskThread','bcTaskThread',taskT) then raise except...;
  55.     (i) This gives you a BLIND THREAD i.e.: ^'type',     ^'name',     ^obj
  56.       taskT.HandleOwner:= Form1.Handle; -then you can do like this
  57.       taskT.MsgQ:= MQ;                  -instead you set
  58.       taskT.DebugMsg:= true;            -properties afterwards
  59.     or "pointer(taskT):= SvcMgr.GetSvcDefaultParams('IbcTaskThread',[Handle,fMsgQ,true]);"
  60.     or "PluginMgr.GetSvcDefaultParams('IbcTaskThread',[Handle,fMsgQ,true],taskT)"
  61.                                     i.e.:  ^type,     [^hForm,^MsgQ,^debugMsg(true/false)],obj
  62.     (!) NOTE: creating the thread with NIL as MsgQueue will give you NO MESSAGES!
  63.                setting 'DebugMsg' to false will have the same effect -^^-^^^^^^^^  
  64.     (!) NOTE: Don't start 2 threads right after another, leave a little pause ~ 2 msecs between
  65.     (!) REMEMBER e.g.: itaskT.Obj.Free; when you're done (corba) }
  66.   ITaskThread = interface(ICorba)[SGUIDITaskThread]
  67.     { property getters and setters }
  68.     function get_Debug: boolean;  
  69.     function get_HandleOwner: ptrint;
  70.     function get_Loaded: boolean;
  71.     function get_MsgQ: IbcMessageQueue64;
  72.     function get_Sleeping: boolean;
  73.     function get_Tcr: PThreadCtrlRec;
  74.     procedure set_Debug(aValue: boolean);
  75.     procedure set_HandleOwner(aValue: ptrint);
  76.     procedure set_MsgQ(aValue: IbcMessageQueue64);
  77.     procedure set_Tag(aValue: ptrint); // property
  78.     function Tag: ptrint; // property
  79.     { runs an extended TNotifyEvent, don't forget to synchronize / protect }
  80.     procedure CallEventEx(aTask: TTaskEventEx;anObj: TObject;aPtr: pointer);
  81.     { ExecTask carries out the specified task with the provided data, params:
  82.         aTask = a procedure that encapsulates the task at hand
  83.         aData = a pointer to the data necessary for the task to complete;
  84.       if the task produces a result, it must be returned in the 'aData' object.
  85.       Note: REMEMBER synchronization / protection of 'aData' }
  86.     procedure ExecTask(aTask: TTaskProc;aData: pointer);
  87.     { runs a standard TNotifyEvent, don't forget to synchronize / protect }
  88.     procedure RunEvent(aTask: TTaskEvent;aData: TObject);
  89.     { StartTask carries out the specified task with the provided data, params:
  90.         aTask = a function that encapsulates the task at hand (same as for 'BeginThread')
  91.         aData = a pointer to the data necessary for the task to complete;
  92.       if the task produces a result, it must be returned in the 'aData' object.
  93.       Note: REMEMBER synchronization / protection of 'aData' }
  94.     procedure StartTask(aTask: TTaskFunc;aData: pointer);
  95.     function Terminate: boolean;
  96.     property DebugMsg: boolean read get_Debug write set_Debug;
  97.     property HandleOwner: ptrint read get_HandleOwner write set_HandleOwner;
  98.     property Loaded: boolean read get_Loaded;
  99.     property MsgQ: IbcMessageQueue64 read get_MsgQ write set_MsgQ;
  100.     property Sleeping: boolean read get_Sleeping;
  101.     property Tcr: PThreadCtrlRec read get_Tcr;
  102.   end;
  103.   { IbcSleepingThread adds the possibility to change msgQ on the fly (not that you should);
  104.     can be woken up to perform a task; be it a taskprocedure, a taskfunction(ThreadFunc) or a:
  105.     e.g.: 'class procedure ExecWait(Arg: pointer); static;' declared in a TForm \o/
  106.     Creation = "constructor Create(hOwner: ptrint; aMsgQ: IbcMessageQueue64; aDbgMsg: boolean);"
  107.     messages posted in MsgQueue by the thread:
  108.       3683 = ENTE(r)  -> entering execute
  109.       2344 = BEGI(n)  -> starting task
  110.       3464 = FINI(sh) -> finished task
  111.       3663 = DONE     -> going to sleep
  112.       7867 = STOP     -> exiting execute, going out of business
  113.       -1   = ERRO(r)  -> caught some kind of error, text is in message.
  114.     (!) NOTE: creating the thread with NIL as MsgQueue will give you NO MESSAGES!
  115.                setting 'DebugMsg' to false will have the same effect -^^-^^^^^^^^
  116.     (!) NOTE: Don't start 2 threads right after another, leave a little pause ~ 2 msecs between
  117.     (!) REMEMBER e.g.: itaskT.Obj.Free; when you're done (corba) }
  118.   ISleepingThread = interface(ITaskThread)[SGUIDISleepingThread] end; { ISleepingThread }
  119. {$Interfaces COM} { refcounting back ON }
  120.   { TThreadCtrlRec carries support data for each thread }
  121.   TThreadCtrlRec = record
  122.     tcDataF: pointer;          { data for use in task-f }
  123.     tcDataP: pointer;          { data for use in task-p & taske-eventex }
  124.     tcEvent: IEvent;           { an event that controls the sleeping }
  125.     tcObjEv: TObject;          { data for use in task-event & taske-eventex }
  126.     tcSleeping: boolean;       { is the thread sleeping }
  127.     tcTerminated: boolean;     { has the thread been shutdown? }
  128.     tcThread: TTaskThread;     { a working thread, that sleeps and then carries out its task }
  129.   end; { TThreadCtrlRec }
  130.  
The above is housed in an .inc file...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

paule32

  • Hero Member
  • *****
  • Posts: 563
  • One in all. But, not all in one.
Re: I lost in Code ...
« Reply #20 on: May 27, 2025, 11:18:22 am »
@odbc
Thank you for your catch-grocceries  ;D

I have to do some work in the kitchen on daylie week - so, I have to look how to split my free time with work time.

All Code is experimental - I am not a pro - so, don't cry about my efforts.
Feel free to drop a message if you have Question's about the Code or Part's of the Code...

I'll be do my best, to get a working Result...

Including @fibonacci - the team leader.

EDIT:
@440bx

and what is your opinion, when UPX comes from a secure source like the FPC + Lazarus main server ?
I think that the sources of UPX be laying by open source ?
« Last Edit: May 27, 2025, 12:13:10 pm by paule32 »
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: I lost in Code ...
« Reply #21 on: May 27, 2025, 12:17:14 pm »
The problem is not UPX which is fine, but unpacking and executing binaries in memory.
So anti-virus software chokes.
Unpacking can not be done in-place by its very nature.

It is very easy to mis-use UPX or equivalent packers.

In the olden days I used it a lot to save disk space, but that is not really relevant anymore, because even a 128GB USB stick or memory card is $5.
« Last Edit: May 27, 2025, 12:25:38 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

440bx

  • Hero Member
  • *****
  • Posts: 5575
Re: I lost in Code ...
« Reply #22 on: May 27, 2025, 12:23:15 pm »
EDIT:
@440bx

and what is your opinion, when UPX comes from a secure source like the FPC + Lazarus main server ?
I think that the sources of UPX be laying by open source ?
It's not about where the UPX exe comes from. 

What I don't like about it is that by compressing the exe, it deceives the user into believing that the exe is smaller than it actually is.  Essentially, that dislike applies to any utility that compresses executables, not just UPX.

The other thing I don't like about it (them, actually), is that it requires the data to be decompressed before it can be executed.  It is questionable that compressing the exe makes it ready to execute sooner.  In addition to that, the decompression process is yet another thing that can go wrong, i.e, if the exe does not behave as expected, is it because of a bug in the exe or is it because the decompression is faulty ?

IOW, way too many real and potential problems to save a few kilobytes.  It just isn't worth the potential hassle.

As @Thaddy posted, there could also be problems related to antiviruses too.  Again, the size gain is paltry at best and, the potential problems quite annoying.  It just isn't worth it.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: I lost in Code ...
« Reply #23 on: May 27, 2025, 12:34:16 pm »
Btw, the bug report to remove UPX from the standard distribution was by me and Florian agreed.
UPX used to be part of the standard distribution up until fpc 2.6.4.
Just to give context.

What UPX does is:
- Use the MAIN entry point to enter its decompression code.
- Allocate sufficient memory to decompress
-  Decompress and move the code
- Change entry point to the real code
- Execute it

That is called hackery.. 8)

It was brilliant in its time, but lost its purpose.
« Last Edit: May 27, 2025, 12:44:10 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

paule32

  • Hero Member
  • *****
  • Posts: 563
  • One in all. But, not all in one.
Re: I lost in Code ...
« Reply #24 on: May 27, 2025, 12:43:12 pm »
okay, I will privately use UPX, and when I distribute the binaries someone I will do it without UPX.

But it is a wide way to do this - because @fibonacci don't want open source.

And it is not guranteed, that our Project life in 5 years are on the Top of i386 Intel / amd64 - because Microsoft seems to be going to little ARM Terminals (no any more the Big Tower PC's in at the Service Desk's or in the private Home Room's by End-User) in the nearly Future.

So, I would not write many Assembly Routines and get the Pascal way.
This can be a Spot of Performance - but I think: better a running System instead stuckle in abroud Assembly Code...
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: I lost in Code ...
« Reply #25 on: May 27, 2025, 12:46:46 pm »
UPX itself has a VERY permissive license, so no, no problems. If it is sane is another matter:
Better write a good installer, these compress too, but just once decompress.

@Fibonacci? Why put him on the wrong track?
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

paule32

  • Hero Member
  • *****
  • Posts: 563
  • One in all. But, not all in one.
Re: I lost in Code ...
« Reply #26 on: May 27, 2025, 12:56:31 pm »
@Fibonacci? Why put him on the wrong track?

I glued / thinking he is train me for a Team Project for a Firm/Corporation.
And in a bigger Firm or little Corporation, there a many Protocolls and Papers that guide the Programmers what an Application shall have in and what not (for a Release or Business-Plan).

I can not write or speak about the Project - because I am not admited to this.
And who knows - maybe he will protect me before the Sharks in the Internet Green and Gray Ground.

He give me Hints and Notes in a way like a Coucher - but without buy knowledge in with money.
This is a great deal:
- I learn new things
- he get a level deeper to rest a little bit and get Power for new Projects - Like a Person that hold his Firm/Corporation running on with new Product's and Service's ...
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

ASBzone

  • Hero Member
  • *****
  • Posts: 724
  • Automation leads to relaxation...
    • Free Console Utilities for Windows (and a few for Linux) from BrainWaveCC
Re: I lost in Code ...
« Reply #27 on: May 28, 2025, 04:12:25 am »
IOW, way too many real and potential problems to save a few kilobytes.  It just isn't worth the potential hassle.

It's a "solution" for a problem that no longer exists in mainstream computing environments, and now causes more problems than it solves.
-ASB: https://www.BrainWaveCC.com/

Lazarus v4.1.0.0 (c067bd336e) / FreePascal v3.2.3-1411-g8c665e3128 (aka fixes)
(Windows 64-bit install w/Win32 and Linux on ARM and x64 cross-compilers via FpcUpDeluxe)

My Systems: Windows 10/11 Pro x64 (Current)

PascalDragon

  • Hero Member
  • *****
  • Posts: 6035
  • Compiler Developer
Re: I lost in Code ...
« Reply #28 on: June 02, 2025, 10:33:35 pm »
I think that putting the entire FPC RTL in a dll is a good idea.  Making it usable by any program might not be simple if the compiler insists on always including the RTL in the executable.

Having the RTL in a dll might even solve some problems in addition to sharing more code and making executables smaller.

Well, with dynamic packages the result for chmls on Windows 64-bit back in 2019 were as follows:

Code: [Select]
1419896 chm.dll
1187518 fcl.base.dll
568559  fcl.res.dll
1602915 fcl.xml.dll
8347    rtl.c.dll
89978   rtl.console.dll
3647275 rtl.dll
345340  rtl.extra.dll
459357  rtl.generics.dll
601446  rtl.objpas.dll
85131   chmls.exe

it's rather unlikely that the entire RTL can be put in a dll given that functions like writeln cannot be accurately described as an export.

As said, with dynamic packages that can be done, however they rely on compiler functionality so they can't be used with other languages/compilers.

Though dynamic packages aren't yet ready for prime time due to some problems that still exist on some platforms and the missing functionality to dynamically load packages at runtime (which is what Lazarus would use).

 

TinyPortal © 2005-2018