Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-06

Strings and objects crossing dll boundaries

3 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

kyan

Hello all,

A couple of questions regarding handling of strings, dynamic arrays and objects -especially exceptions- when writing programs that use shared libraries (.dll, .so).

In Delphi we have the option of either using packages to ensure that there is only one instance of the memory allocator or use ShareMem.pas that installs a memory allocator that can handle memory allocations across libraries. Given that in FPC/Lazarus there are no "packages" in the Delphi sense what is the equivalent of ShareMem.pas? Is it cmem.pp?

Regarding objects, in Delphi an object cannot safely cross dll boundaries because separate class record(s) for it exist in each executable file. OK, actually it can if one is certain that the class records compiled in each executable are identical. But if an exception crosses dll boundaries then you are in trouble, because the operator "is" does not work due to the class pointer that points to another Exception class record than the one known by the handling executable. The best way to solve this is to put the class Exception at least inside a package that all executables use so at least "is" will work for Exception. Is there a way to handle this problem in FPC that does not have packages?

TIA

Constantine.

Reply by email

Marco van de Voort
to kyan

In our previous episode, kyan said:

Show quoted text 19 lines
A couple of questions regarding handling of strings, dynamic arrays and objects -especially exceptions- when writing programs that use shared libraries (.dll, .so). In Delphi we have the option of either using packages to ensure that there is only one instance of the memory allocator or use ShareMem.pas that installs a memory allocator that can handle memory allocations across libraries. Given that in FPC/Lazarus there are no "packages" in the Delphi sense what is the equivalent of ShareMem.pas? Is it cmem.pp? Regarding objects, in Delphi an object cannot safely cross dll boundaries because separate class record(s) for it exist in each executable file. OK, actually it can if one is certain that the class records compiled in each executable are identical. But if an exception crosses dll boundaries then you are in trouble, because the operator "is" does not work due to the class pointer that points to another Exception class record than the one known by the handling executable.

(and AS as it implies IS). Yes, all true.

The best way to solve this is to put the class Exception at least inside a package that all executables use so at least "is" will work for Exception. Is there a way to handle this problem in FPC that does not have packages?

The Delphi packages concept consists out two key factors:

- the model that any metadata and RTL/program state only exists once in the process (EXE+DLLs combined)
- the way to easily achieve this. Basically Delphi requires to arrange units into packages in ways that observe the dependency rules for packages, and the rest is fairly automated.

FPC does definitely not support the latter.

The former however (manually arranging for this uniqueness of state and metadata) might be possible under certain circumstances. There are multiple reports about that (see among others
http://bugs.freepascal.org/view.php?id=12492 ), but whatever information there is, is fragmented in bits and pieces, and there are no real structure howtos. Most are on Linux also.

Reply by email

Mark Morgan Lloyd
to kyan: A couple of questions regarding handling of strings, dynamic arrays and objects…
kyan wrote 5 lines
Hello all, A couple of questions regarding handling of strings, dynamic arrays and objects -especially exceptions- when writing programs that use shared libraries (.dll, .so).

This seems to be a hot topic at the moment.

Show quoted text 6 lines
In Delphi we have the option of either using packages to ensure that there is only one instance of the memory allocator or use ShareMem.pas that installs a memory allocator that can handle memory allocations across libraries. Given that in FPC/Lazarus there are no "packages" in the Delphi sense what is the equivalent of ShareMem.pas? Is it cmem.pp?

Yes. A reference to cmem should appear as the first entry in the uses statement of earliest-executed unit, i.e. assuming Lazarus this is the .lpr file. If using heaptrc this has to be put as the next entry, FPC's -gh won't work, but I don't know to what extent having heaptrc in both the main program and the library is workable (and various people are currently mentioning heaptrc problems possibly caused by inadvertent optimisation).

Regarding objects, in Delphi an object cannot safely cross dll boundaries because separate class record(s) for it exist in each executable file. OK, actually it can if one is certain that the class records compiled in each executable are identical.

Agreed. However I'd suggest better terminology would be something like "cannot safely be referenced across", simply saying "crossing" is too evocative of "crossing a 64K boundary" for us old-timers :-)

Having said that, I'm successfully referencing (non-short) strings across the divide, doing a deep-copy of TMenuItems from a form designed in the shared library (which is there purely as a placeholder for menu entries, and executing click events associated with menu items (which work because they get a sender when invoked). I'm moving onto more complex stuff shortly /but/ due to design requirements will be handling this by passing parseable text commands, i.e. the backend can tell the frontend to change the UI state (without full knowledge of the current state) and the frontend can tell the backend to change state (with the same limitation).

But if an exception crosses dll boundaries then you are in trouble, because the operator "is" does not work due to the class pointer that points to another Exception class record than the one known by the handling executable.

Generally agreed.

The best way to solve this is to put the class Exception at least inside a package that all executables use so at least "is" will work for Exception. Is there a way to handle this problem in FPC that does not have packages?

Not knowing, can't say. Looking at the larger picture, I don't know how one best debugs operation as control is transferred from the main program into the shared library, bearing in mind that this might be important since the library might have all the tricky code.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email