Mark Morgan Lloyd wrote:
Tomas Hajny wrote:
On Wed, July 4, 2012 11:32, Mark Morgan Lloyd wrote:
When building a shared library, I'm putting a (function that returns a)
magic number into both the library and the calling program. This returns
an integer, and allows the program and library to check their exposed
APIs without risk.
How can code in the library test whether it is using cmem, so that it
can tell the caller that it's safe to call functions that move strings
and objects around? It's obviously trivial to rely on a compile-time
conditional, but can this be done in a way that doesn't rely on this?
First of all, you can easily check whether the default memory manager is
used by calling IsMemoryManagerSet. Obviously, this doesn't tell whether
the custom memory manager is cmem or something else (e.g. TraceManager
from HeapTrace). However, you could possibly try to check the distance
between the individual MemoryManager methods retrieved using
GetMemoryManager - while that is not bulletproof by any means, it
provides
at least some indication.
Finally, if there are certain major changes to features provided by
individual memory managers (like some operation being safe or not),
adding
some TMemoryManager method allowing to provide this information may be
the
best solution for the future.
Thanks Tomas (and Ludo). Under the circumstances I think
IsMemoryManagerSet is probably an adequate solution, since the real risk
is that somebody messes about with the start of the main unit (or with
the project settings) without appreciating that the cmem import is
crucial to operation elsewhere in the program (or, analogously, that a
shared library will crash when some functions are called).
Having something- e.g. an exported string- in cmem would be a partial
solution, but would have to be checked in the main unit. With any
solution, I think that testing that cmem was the first import could be a
challenge.
I've added a feature request as
http://mantis.freepascal.org/view.php?id=22386 but am being told "First
of all, you are wrong in thinking that using Cmem is a prerequisite to
being able to use longstrings etc. as parameters and results..."
Obviously I accept that there might be other suitable memory managers,
but cmem is the one normally referred to. Far be it from me to argue
with those more experienced than I, but the suggestion I'm trying to
make is that it would be desirable if each module (i.e. every shared
library plus the main program) could confirm that it's in a state where
it can share e.g. longstrings, objects etc. with others. In common
usage, that implies that cmem is not only imported, but is imported /first/.
--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal