[Lazarus] "Running" a library

Mark Morgan Lloyd markMLl.lazarus at telemetry.co.uk
Sat Sep 15 13:38:03 CEST 2012


Sven Barth wrote:
> On 15.09.2012 13:12, Mark Morgan Lloyd wrote:
>> Sven Barth wrote:
>>> On 15.09.2012 12:36, Mark Morgan Lloyd wrote:
>>>> Sven Barth wrote:
>>>>
>>>>>> /Why/ can't a library be run standalone? We're already at the 
>>>>>> position
>>>>>> that an executable can decide whether it's been invoked from a
>>>>>> shell or
>>>>>> the GUI and behave as appropriate, so why can't it decide whether 
>>>>>> it's
>>>>>> being run as a program or being initialised as a library?
>>>>>
>>>>> A library and an application have different entry point signatures.
>>>>> Take Windows for example. There the entry point for applications is
>>>>> "procedure EntryPoint; stdcall;" while for DLLs it is "procedure
>>>>> EntryPoint(aHinstance: PtrInt; aDLLReason: Word; aDLLParam: Pointer);
>>>>> stdcall;". Additionally the entry point of a DLL is called multiple
>>>>> times (once the process loads the library, every time a new thread is
>>>>> created and destroyed and once the process unloads the library) while
>>>>> the entry point of an application is only called once. Also AFAIK
>>>>> Windows does not let you run binaries that are flagged as "DLL".
>>>>> That's the reason why there is a program called "rundll32" ;) [though
>>>>> it expects an exported function with a certain signature...]
>>>>
>>>> Assuming for a moment that a binary can be built that is basically an
>>>> executable but also exports library-style entry points, and which could
>>>> be loaded into memory using DynLib or whatever: could the 
>>>> initialisation
>>>> function be told to return fast and cleanly if it detected that it
>>>> wasn't being run as a program? In that case, the caller could use 
>>>> DynLib
>>>> to load it and then invoke a different entry point explicitly to handle
>>>> initialisation.
>>>>
>>>
>>> You are able to define exports from a program. And you can also load
>>> the program binary using LoadLibrary from a library that is already
>>> loaded from that program (because the entry point is not called then),
>>
>> I'm already calling from a loaded library back into the calling program
>> using that technique. What happens if a library tries to load a
>> /different/ program: is the main entry point called and are the
>> subsidiary entry points available?
>>
> 
> I currently only have one answer for that: try it and see what happens.

Will do, but not today. I'll report back.

>>> but you can not build an application that can be used also as a
>>> dynamic library, because as I already wrote the entry point signatures
>>> are different and thus if you would e.g. use the DLL's signature for
>>> the program your code would expect parameters (aHinstance, aDLLReason
>>> and aDLLParam) where the OS did not pass you anything ( => stack
>>> corruption).
>>
>> Although the called code might be able to determine that the parameters
>> aren't valid and react accordingly, and being stdcall (unless my
>> understanding is outdated) it's the caller that restores the stack state.
>>
> 
> In cdecl it's the caller, because of varargs functions which are not 
> possible with e.g. stdcall as there the callee is responsible.

Thanks for refreshing my memory.

-- 
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]




More information about the Lazarus mailing list