Difference between revisions of "shared library/es"

From Lazarus wiki
Jump to navigationJump to search
 
(26 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Shared Library}}
+
{{shared library}}
 +
[[category:Castellano|S]][[category:Español|S]]
  
(Al decir librería compartida se hace alusión tanto a .so como a .dll, a no ser que se diga "librería compartida de unix" o "dll" explicitamente)
+
   Una librería compartida es una pieza de código compilado que puede ser compartido y utilizado por varios programas. Proporciona funciones y procedimientos que otros programas pueden llamar.
  
Hoy día hay una gran cantidad de informes de error sobre las librerías compartidas. Sin embargo, que yo sepa, no hay una verdadera documentación acerca de cómo las librerías compartidas trabajan conjuntamente con FPC. Trataremos de como trabajan las librerías compartidas, cómo deberían hacerlo, y de cómo se hace esto con Delphi.
+
   Es diferente de una librería estática, que está vinculada a un archivo ejecutable y se convierte en parte de ella, o un ejecutable.
  
En principio esto es un bosquejo, de cómo se hace en Delphi, ya que tratermos de hacerlo lo más compatible y multiplataforma que sea posible. Todo lo expuesto está sacado de mi cabeza y de páginas "web". Si deseas más detalle o detallar más exactamente los términos de este trabajo, está invitado a ello.
+
   El término librería compartida se refiere tanto a .so (linux) como a .dll (windows), a no ser que se diga explícitamente "librería compartida de unix" o "dll".
  
Soy un completo desconocedor de Kilix, así que si conoces cómo se implementa en Kilix cierta funcionalidad, no dudes en añadirlo.
+
   Hoy día hay una gran cantidad de informes de error sobre las librerías compartidas. Sin embargo, que yo sepa, no hay una verdadera documentación acerca de cómo las librerías compartidas trabajan conjuntamente con FPC. Trataremos de como trabajan las librerías compartidas, cómo deberían hacerlo, y de cómo se hace esto con Delphi.
 +
 
 +
   En principio esto es un bosquejo, de cómo se hace en Delphi, ya que trataremos de hacerlo lo más compatible y multiplataforma que sea posible. Todo lo expuesto está sacado de mi cabeza y de páginas "web". Si deseas más detalle o detallar más exactamente los términos de este trabajo, está invitado a ello.
 +
 
 +
  Soy un completo desconocedor de Kylix, así que si conoces cómo se implementa en Kylix cierta funcionalidad, no dudes en añadirlo.
  
 
== Delphi ==
 
== Delphi ==
  
Delphi hasta donde sé tine tres (o cuatro) formas de enlace dinámico.
+
   Delphi, hasta donde conozco, tiene tres (o cuatro) formas de enlace dinámico.
  
 
# crear un librería compartida independiente, compilar una librería sin seleccionar paquetes de tiempo de ejecución ("runtime packages").
 
# crear un librería compartida independiente, compilar una librería sin seleccionar paquetes de tiempo de ejecución ("runtime packages").
#* Esto implica que la RTL será enlazada en la librería compartida
+
#* Esto implica que la Librería de Tiempo de Ejecución (RTL) será enlazada en la librería compartida
 
#* El controlador de memoria está aislado. La utilización de tipos automáticos para comunicarse con ella no será posible.
 
#* El controlador de memoria está aislado. La utilización de tipos automáticos para comunicarse con ella no será posible.
#* No se podrán usar clases. El programa y la librería tienen copias distintas de la VMT. (¡¿e.g. operadores IS y AS?!)
+
#* No se podrán usar clases. El programa y la librería tienen copias distintas de la Tabla de Métodos Virtuales (VMT). (¡¿e.g. operadores IS y AS?!)
 
# crear un librería compartida independiente (compilar una librería (unit library) sin seleccionar paquetes de tiempo de ejecución ("runtime packages"), pero usando la unidad '''sharemem'''
 
# crear un librería compartida independiente (compilar una librería (unit library) sin seleccionar paquetes de tiempo de ejecución ("runtime packages"), pero usando la unidad '''sharemem'''
#* la RTL será enlazada en la librería compartida
+
#* La RTL será enlazada en la librería compartida
 
#* El controlador de memoria estará en modo  compatible COM. Esto permitirá a otros componentes/programas, funcionado en este mismo modo realizar llamadas a funciones usando tipos automáticos (no importa lo que se devuelve al COM manejado)
 
#* El controlador de memoria estará en modo  compatible COM. Esto permitirá a otros componentes/programas, funcionado en este mismo modo realizar llamadas a funciones usando tipos automáticos (no importa lo que se devuelve al COM manejado)
 
#* Reseñar la lentitud del manejador COM de memoria. Esta vía es poco recomendable, a no ser que se quiera a toda costa COM o que los "COMponentes" sean más importantes que que la velocidad de ejecución.
 
#* Reseñar la lentitud del manejador COM de memoria. Esta vía es poco recomendable, a no ser que se quiera a toda costa COM o que los "COMponentes" sean más importantes que que la velocidad de ejecución.
 
#* No se podrán usar clases. El programa y la librería tienen copias distintas de la VMT.
 
#* No se podrán usar clases. El programa y la librería tienen copias distintas de la VMT.
# [[packages|Library packages]] These are shared libraries for which all dependancies on pascal level are known (which units they contain and depend on), and can be treated as parts of the main program that reside in a DLL.
+
# [[packages|Library packages]] Estas son librerías compartidas para las cuales todas las dependencias a nivel pascal son conocidas (que unidades lo contienen y que dependencias existen), y son tratadas como si fuesen parte del programa principal que residen en una DLL.
#* The RTL is in a separate package(DLL), and both the mainprogram and package use it. Therefore there is only one copy of any unit including system.
+
#* La RTL es un paquete separado (una DLL) y el programa principal y los otros paquetes hacen uso de la misma. Todo esto implica que únicamente hay una copia de cada unidad en el sistema.
#* This also means there is only one memory manager (at least for the mainprogram and the packages it uses. IOW shared libs that are not a package can still use an own RTL and memory manager)
+
#* Esto también significa que hay sólo un administrador de memoria (al menos para el programa principal y los paquetes que utiliza. Las librerías compartidas que no son paquetes pueden utilizar su propia copia de la RTL y su manejador de memoria)
#* a package can only depend on units in its own package or in other packages.
+
#* un paquete sólo puede depender de unidades de su propio paquete o de otros paquetes.
#* because no units are duplicated, there is only one copy of each VMT, making classes use transparent.
+
#* como las unidades no se duplican existe una única copia de cada VMT, haciendo transparente la utilización de las clases
#* Probably packages can also switch to sharemem, making it compatible with other sharemem using systems. Some way must be found to initialise sharemem as early as possible though (does Delphi do this? Possible test for this is to pass an ansistring created in a init section of a unit in a package to a different sharemem using shared lib that is not a package) T.B.D.
+
#* Es probable que los paquetes también puedan cambiar a "memoria compartida", lo que lo hace compatible con otros sistemas que utilizan "memoria compartida". Hay que buscar la manera de iniciar la memoria compartida lo antes posible (¿Cómo lo hace Delphi? probablemente intentando pasar una cadena creada en una sección de iniciación de un paquete a otra librería compartida, que no es un paquete, que usa memoria compartida) T.B.D.
 +
 
 +
   Además de lo anterior Delphi es capaz de producir dll que contienen componentes ''ActiveX''. T.B.D.
  
Besides these, Delphi can also generate dlls that are ActiveX components. T.B.D.
+
   Las cuestiones sobre librerías de paquetes se han trasladado al tema [[packages|paquetes]] para no liar el debate.
  
Topics about library packages are mostly moved from this page to the separate [[packages]] lemma, to not confuse the discussion
+
== Detalles de ''Sharemem''==
  
== Sharemem implementation details ==
+
   Como ya se ha dicho, ''sharemem'' cambia el gestor de memoria a global. Bajo Windows este es el controlador COM, que yo sepa. En *nix un controlador de memoria similar no existe (La arquitectura de componentes de Gnome y KDE puede que hagan algo similar), pero no tengo garantías sobre esto.
  
As said, sharemem switches the memory manager to a global one. Under Windows this is afaik the COM manager. On *nix a similar memmanager doesn't always exist ( Gnome and KDE component architectures might have something similar), but it is not guaranteed there.
+
   Uno podría simplemente tener todos los programas usando "cmem", lo que podría ser un "nivel 0" de todo lo que se ejecuta en este proceso
  
One could probably simply have all programs use cmem, which could be a "level 0" implementation for everything that runs in this process.
+
   Se menciona esto explícitamente porque, podría ser necesario imponer un orden propio de inicio (independiente de la iniciación de las librerías compartidas por el SO) para permitir al programa principal iniciar adecuadamente las unidades después de la iniciación de la RTL (unidad del sistema), pero antes que otras librerías, v.gr. un controlador de memoria diferente.
  
I explictely name this because, it might be necessary to impose an own initialisation order (independant of OS shared lib initialisation) to allow the main program to initialise units right after the RTL (system unit) initializations, but before other libs. e.g. a different memory manager.
+
== Duplicación de la VMT ==
  
== VMT duplication ==
+
   El principal problema de la duplicación de la VMT es el soporte para el parámetro IS y simular métodos de ''TObject'' y ''TClass'' como si fuesen heredados. Esto está resuelto únicamente para paquetes, es decir, para los otros tipos mencionados, el operador IS no funciona en el cruce librería/binario.
  
The basic problem of VMT duplication is mostly support for the IS parameter and simular methods of tobject and tclass like inheritsfrom). This is only solved for packages, IOW for the other two types named above, the IS operator doesn't work across libraries/binaries.
+
   En discusiones anteriores sobre paquetes, hubo cierta confusión sobre esta cuestión. La gente asume que los paquetes de alguna manera aprovechan la VMT de la RTL desde el programa principal. Sin embargo, estoy bastante seguro de que este no es el caso, al menos en Delphi, ya que cuando se utilizan paquetes, la RTL es también un paquete. Y cada dependencia de una unidad en un paquete deben estar en el mismo paquete o en un paquete del que dependa. Esto significa que únicamente hay una copia de una unidad, y de la VMT en ella declarada, en el programa conjunto (el programa principal + sus paquetes)
  
In earlier discussions about packages, there was some confusion about this topic. People assumed that packages would somehow tap into the RTL VMT's in the main binary. I'm however pretty sure this is not the case, at least not in Delphi, since when using packages, the RTL always is a package too. And every dependancy of an unit in a package must be in the same package or in a package it has a dependancy on. This means an unit (and thus, the VMTs declared in it) only exists once in the greater program (main program + its packages)
+
== La RTL y las secciones de iniciación y terminación ==
  
== Initialization and finalization sections and RTL ==
+
   (la explicación sobre el orden de iniciación de las unidades en los paquetes ha sido movida a la página de [[packages|paquetes]]).
  
(the initialization order of units in packages is moved to the packages page).
+
   El problema con las bibliotecas es por lo general que son iniciadas en su conjunto. ESto puede llevar a problemas con unidades conectadas que modifican el comportamiento de la RTL (cwstrings, cmem, controladores FV, etc.)
  
The problem with libraries is usually that libraries are initialized as a whole. This can lead to problems with plugin units modifying RTL behaviour (cwstrings, cmem, FV drivers etc)
+
   Para librerías independientes con copias de la RTL, esta tiene que ser iniciada, y así mismo debe serlo la sección de iniciación de la librería.
  
For stand-alone libraries with internal copies of RTL to function, the RTL needs to be initialized, and the initialization section of the library needs to be called as well.
+
   Hay, al menos, dos opciones para esto:
  
Roughly there are two options here:
+
* Usar (v.gr. en plataformas ELF) las secciones .init y .fini del ABI o mecanismos similares de otros formatos binarios.
 +
* Dejar las secciones .init y .fini vacías, y fuerce el orden de iniciación con secciones propias de inicio y fin. Las secciones ELF de inico y fin simplemente apuntan a los iniciadores (y terminadores) reales.
  
* Use (e.g. on ELF platforms) the ABI .init and .fini sections or similar constructs in other binary formats.
+
   Métodos mixtos son posibles, v.gr. iniciar las librería independientes con secciones de inicio y utilizar las secciones definidas por nosotros mismos con los paquetes.
* Leave the above initializers mostly empty sections, and enforce an own order using a set of own initializers and finalizers. The ELF init and fini sections merely register the real initializers.
 
  
Mixed forms are also possible, e.g. initialize standalone shared libraries via the initializer sections, but with packages use an own definition.
+
== Administrador de Memoria compartida de Exe ==
  
== Shared Exe Memory manager ==
+
   Lars dice: con respecto a un administrador de memoria única para los paquetes de estilo BPL: ¿qué pasa con el ejecutable y la exportación de su gestor de memoria? He tenido problemas tratando de usar CMEM, pero han compartido correctamente el administrador de memoria de la misma utilizando los trucos SetMemoryManager / GetMemoryManager.
Lars says: regarding a single memory manager for BPL style packages: what about using the executable and exporting its memory manager? I have had problems trying to use CMEM but have successfully shared the same memory manager using SetMemoryManager/GetMemoryManager tricks.  
 
  
See http://www.freepascal.org/contrib/delete.php3?ID=543 for an example of sharing memory between exe and dll without using CMEM. Powtils CGI library also uses this trick for dynpwu.pas so that ansistrings can be used without any sharemem or cmem unit. The memory manager is exported from the executable or a single library and shared with all the other DLL/EXE's that are connecting to the single module.
+
   Ver en http://www.freepascal.org/contrib/delete.php3?ID=543 un ejemplo de intercambio de memoria entre EXE y DLL sin utilizar CMEM. La librería ''Powtils CGI'' también utiliza este truco para ''dynpwu.pas'' ya que ''ansistrings'' se debe utilizar sin ningún tipo de unidad ''sharemem'' o ''cmem''. El administrador de memoria se exporta desde un ejecutable o una librería y es compartida con todos los demás DLL / EXE 's que se conectan a este módulo.  
  
Marco's answer:
+
   Respuesta de Marco:  
  
First, library packages have more features than just shared memory managers. Unique VMTs (try to use the IS operator in your example on a class created in the other lib/exe) and no need to handcraft proper initialization. One just groups units into libs, and the compiler does the rest. No special code required.
+
   En primer lugar, los paquetes de librería tienen más funcionalidades que los administradores de memoria compartida. VMTs únicos (trata de usar el operador IS en su ejemplo en una clase creada en el otros lib / exe) y no necesitaras hacer la iniciación correcta manualmente. Agrupa las unidades en una única librería, y el compilador hace el resto. Sin código especial.  
  
So what must be done for (Library-) packages is different (and non competing) to the more general shared library case. And that is what this page is about.
+
   Entonces, lo que debe hacerse para paquetes (de librería) es diferente (y no está reñido) con el caso más general de la librería compartida. Y de esto es lo que esta página trata.  
  
From this general "shared library" case, a subdivision can be separated that have a shared memorymgr.  
+
   Desde el caso general de la ''librería compartida'', una subdivisión puede distinguirse cuando tienen ''memorymgr'' compartida.  
  
Note that there can be a bunch of memory managers used for this, and multiple units that work like sharemem. Nearly any memory manager applies. However it is logical to reserve the "sharemem" unit name for the memory manager that is the most compatible for inter-process work on the given platform (COM on Windows, cmem on Unix). So, I'm talking about the default case here, which doesn't mean that other people can't roll their own.
+
   Ten en cuenta que no puede haber un grupo de administradores de memoria en uso para esto, y varias unidades que funcionen compartiendo memoria. ESto es aplicable a casi cualquier gestor de memoria. Sin embargo, es lógico reservar el nombre de unidad ''sharemem'' para el gestor de memoria que es el más compatible para el trabajo entre procesos en la plataforma determinada (COM en Windows, cmem en Unix). Por lo tanto, estoy hablando del caso por defecto aquí, lo que no significa que otras personas no puedan hcerlo por su propia cuenta.
  
Also, in-compiler(rtl) support must be as universal as possible, and also work for libraries that are not loadlibrary-ed, but autoloaded at binary startup, and not require handcoding e.g. initialization. Also it mustn't stand in the way of handcoded solutions (like the one you reference), in other words it must be overridable, since otherwise in-compiler(rtl) support would stand in the way of what people build on top of FPC.
+
   Además, en el compilador (RTL) el soporte debe ser lo más universal posible, y funcionar también para las librerías que no son cargables, pero se cargan automáticamente al iniciar el ejecutable, y no requieren '"código manual", por ejemplo, de inicialización. Además, no debe interponerse en el camino de las soluciones "manuales" (como la referida), en otras palabras, debe ser reemplazable, ya que de otra manera el soporte del compilador (RTL) obstaculizaría el camino de lo que la gente construye por encima de la FPC.
  
It would be useful though, if sb investigate if it is possible to call exported symbols from the binary from an autoloaded library (for the Tier 1 targets, Linux/FreeBSD - Windows - OS X). This because then a library could maybe indeed plug in the mother binary.
+
   Sería útil sin embargo, si (SB) investigara si es posible usar los símbolos exportados del binario desde una librería cargada automáticamente (para los objetivos de nivel 1, Linux/FreeBSD - Windows - OS X). Esto porque así una librería tal vez podría, de hecho,  conectarse en el binario ''madre''.
  
In short the first objective is to simply have a default scheme that works like Delphi's sharemem to put in the "sharemem" unit.
+
   En breve, el primer objetivo es, simplemente, tener un esquema por defecto que funcione como el ''sharemem'' de Delphi para poner en la unidad "sharemem" .
  
Lars says: Well another idea: instead of exporting the memory manager from the exe I was thinking about making a fpsharemem.dll that exports one single common fpc memory manager on each platform for all the programs and dll's to use, instead of using CMEM. i.e. all units put fpsharemem.dll in their uses clause. In fact, that's actually what the demo does but instead of a separate fpsharemem.dll it is just inside that single dll included with the demo and all the other code. i.e. why use CMEM if we can use freepascal memory manager? The freepascal mem manager is available on all platforms isn't it, as long as there is a fp dll is created for each platform?
+
   Lars dice: bueno, otra idea: en lugar de exportar el administrador de memoria del EXE, yo pensaba en hacer una ''fpsharemem.dll'' que exportara un único gestor de memoria fpc común en cada plataforma para uso de todos los programas y las DLL, en lugar de utilizar CMEM, es decir, todas las unidades pondrían ''fpsharemem.dll'' en su cláusula uses. De hecho, eso es realmente lo que la demo hace simplemente, en lugar de un fpsharemem.dll separado, es justo dentro de esa única DLL incluida en la demo y el resto del código, es decir, ¿por qué usar CMEM si podemos usar el gestor de memoria FreePascal? El gestor de memoría FreePascal está disponible en todas las plataformas, ¿no, siempre hay una dll FP para cada plataforma?
  
I guess to answer my own questions it must have to do with COM/IPC (inter process communication) issues/compatibilities. Well anyway, still a very interesting discussion. Doing it by hand the way I did was just a demo to show the concept in action and to prove to people that ansistrings and automated types can be used in regular old DLL's.
+
   He intentado responder a mis propias preguntas sobre la cuestión de la compatibilidad COM/IPC (comunicación entre procesos). Bueno de todos modos, sigue siendo un debate muy interesante. He tomado el camino de hacer una demostración para mostrar el concepto en la acción y para demostrar que ''ansistrings'' y tipos automatizado puede ser utilizados en una DLL normal de las de antes.
  
 
== References ==
 
== References ==
  
* http://www.iecc.com/linker/
+
* http://www.iecc.com/linker/ (no funciona, ¿será esta?: http://linker.iecc.com/)
 
* ftp://ftp.freepascal.org/pub/fpc/docs-pdf/CinFreePascal.pdf
 
* ftp://ftp.freepascal.org/pub/fpc/docs-pdf/CinFreePascal.pdf
 +
 +
== Contribuciones ==
 +
* Versión en castellano (español) [[User:Iskraelectrica | iskraelectrica (jldc)]] / enero de 2010.

Latest revision as of 03:01, 31 March 2013

Deutsch (de) English (en) español (es) 한국어 (ko) русский (ru)

   Una librería compartida es una pieza de código compilado que puede ser compartido y utilizado por varios programas. Proporciona funciones y procedimientos que otros programas pueden llamar.

   Es diferente de una librería estática, que está vinculada a un archivo ejecutable y se convierte en parte de ella, o un ejecutable.

   El término librería compartida se refiere tanto a .so (linux) como a .dll (windows), a no ser que se diga explícitamente "librería compartida de unix" o "dll".

   Hoy día hay una gran cantidad de informes de error sobre las librerías compartidas. Sin embargo, que yo sepa, no hay una verdadera documentación acerca de cómo las librerías compartidas trabajan conjuntamente con FPC. Trataremos de como trabajan las librerías compartidas, cómo deberían hacerlo, y de cómo se hace esto con Delphi.

   En principio esto es un bosquejo, de cómo se hace en Delphi, ya que trataremos de hacerlo lo más compatible y multiplataforma que sea posible. Todo lo expuesto está sacado de mi cabeza y de páginas "web". Si deseas más detalle o detallar más exactamente los términos de este trabajo, está invitado a ello.

  Soy un completo desconocedor de Kylix, así que si conoces cómo se implementa en Kylix cierta funcionalidad, no dudes en añadirlo.

Delphi

   Delphi, hasta donde conozco, tiene tres (o cuatro) formas de enlace dinámico.

  1. crear un librería compartida independiente, compilar una librería sin seleccionar paquetes de tiempo de ejecución ("runtime packages").
    • Esto implica que la Librería de Tiempo de Ejecución (RTL) será enlazada en la librería compartida
    • El controlador de memoria está aislado. La utilización de tipos automáticos para comunicarse con ella no será posible.
    • No se podrán usar clases. El programa y la librería tienen copias distintas de la Tabla de Métodos Virtuales (VMT). (¡¿e.g. operadores IS y AS?!)
  2. crear un librería compartida independiente (compilar una librería (unit library) sin seleccionar paquetes de tiempo de ejecución ("runtime packages"), pero usando la unidad sharemem
    • La RTL será enlazada en la librería compartida
    • El controlador de memoria estará en modo compatible COM. Esto permitirá a otros componentes/programas, funcionado en este mismo modo realizar llamadas a funciones usando tipos automáticos (no importa lo que se devuelve al COM manejado)
    • Reseñar la lentitud del manejador COM de memoria. Esta vía es poco recomendable, a no ser que se quiera a toda costa COM o que los "COMponentes" sean más importantes que que la velocidad de ejecución.
    • No se podrán usar clases. El programa y la librería tienen copias distintas de la VMT.
  3. Library packages Estas son librerías compartidas para las cuales todas las dependencias a nivel pascal son conocidas (que unidades lo contienen y que dependencias existen), y son tratadas como si fuesen parte del programa principal que residen en una DLL.
    • La RTL es un paquete separado (una DLL) y el programa principal y los otros paquetes hacen uso de la misma. Todo esto implica que únicamente hay una copia de cada unidad en el sistema.
    • Esto también significa que hay sólo un administrador de memoria (al menos para el programa principal y los paquetes que utiliza. Las librerías compartidas que no son paquetes pueden utilizar su propia copia de la RTL y su manejador de memoria)
    • un paquete sólo puede depender de unidades de su propio paquete o de otros paquetes.
    • como las unidades no se duplican existe una única copia de cada VMT, haciendo transparente la utilización de las clases
    • Es probable que los paquetes también puedan cambiar a "memoria compartida", lo que lo hace compatible con otros sistemas que utilizan "memoria compartida". Hay que buscar la manera de iniciar la memoria compartida lo antes posible (¿Cómo lo hace Delphi? probablemente intentando pasar una cadena creada en una sección de iniciación de un paquete a otra librería compartida, que no es un paquete, que usa memoria compartida) T.B.D.

   Además de lo anterior Delphi es capaz de producir dll que contienen componentes ActiveX. T.B.D.

   Las cuestiones sobre librerías de paquetes se han trasladado al tema paquetes para no liar el debate.

Detalles de Sharemem

   Como ya se ha dicho, sharemem cambia el gestor de memoria a global. Bajo Windows este es el controlador COM, que yo sepa. En *nix un controlador de memoria similar no existe (La arquitectura de componentes de Gnome y KDE puede que hagan algo similar), pero no tengo garantías sobre esto.

   Uno podría simplemente tener todos los programas usando "cmem", lo que podría ser un "nivel 0" de todo lo que se ejecuta en este proceso

   Se menciona esto explícitamente porque, podría ser necesario imponer un orden propio de inicio (independiente de la iniciación de las librerías compartidas por el SO) para permitir al programa principal iniciar adecuadamente las unidades después de la iniciación de la RTL (unidad del sistema), pero antes que otras librerías, v.gr. un controlador de memoria diferente.

Duplicación de la VMT

   El principal problema de la duplicación de la VMT es el soporte para el parámetro IS y simular métodos de TObject y TClass como si fuesen heredados. Esto está resuelto únicamente para paquetes, es decir, para los otros tipos mencionados, el operador IS no funciona en el cruce librería/binario.

   En discusiones anteriores sobre paquetes, hubo cierta confusión sobre esta cuestión. La gente asume que los paquetes de alguna manera aprovechan la VMT de la RTL desde el programa principal. Sin embargo, estoy bastante seguro de que este no es el caso, al menos en Delphi, ya que cuando se utilizan paquetes, la RTL es también un paquete. Y cada dependencia de una unidad en un paquete deben estar en el mismo paquete o en un paquete del que dependa. Esto significa que únicamente hay una copia de una unidad, y de la VMT en ella declarada, en el programa conjunto (el programa principal + sus paquetes)

La RTL y las secciones de iniciación y terminación

   (la explicación sobre el orden de iniciación de las unidades en los paquetes ha sido movida a la página de paquetes).

   El problema con las bibliotecas es por lo general que son iniciadas en su conjunto. ESto puede llevar a problemas con unidades conectadas que modifican el comportamiento de la RTL (cwstrings, cmem, controladores FV, etc.)

   Para librerías independientes con copias de la RTL, esta tiene que ser iniciada, y así mismo debe serlo la sección de iniciación de la librería.

   Hay, al menos, dos opciones para esto:

  • Usar (v.gr. en plataformas ELF) las secciones .init y .fini del ABI o mecanismos similares de otros formatos binarios.
  • Dejar las secciones .init y .fini vacías, y fuerce el orden de iniciación con secciones propias de inicio y fin. Las secciones ELF de inico y fin simplemente apuntan a los iniciadores (y terminadores) reales.

   Métodos mixtos son posibles, v.gr. iniciar las librería independientes con secciones de inicio y utilizar las secciones definidas por nosotros mismos con los paquetes.

Administrador de Memoria compartida de Exe

   Lars dice: con respecto a un administrador de memoria única para los paquetes de estilo BPL: ¿qué pasa con el ejecutable y la exportación de su gestor de memoria? He tenido problemas tratando de usar CMEM, pero han compartido correctamente el administrador de memoria de la misma utilizando los trucos SetMemoryManager / GetMemoryManager.

   Ver en http://www.freepascal.org/contrib/delete.php3?ID=543 un ejemplo de intercambio de memoria entre EXE y DLL sin utilizar CMEM. La librería Powtils CGI también utiliza este truco para dynpwu.pas ya que ansistrings se debe utilizar sin ningún tipo de unidad sharemem o cmem. El administrador de memoria se exporta desde un ejecutable o una librería y es compartida con todos los demás DLL / EXE 's que se conectan a este módulo.

   Respuesta de Marco:

   En primer lugar, los paquetes de librería tienen más funcionalidades que los administradores de memoria compartida. VMTs únicos (trata de usar el operador IS en su ejemplo en una clase creada en el otros lib / exe) y no necesitaras hacer la iniciación correcta manualmente. Agrupa las unidades en una única librería, y el compilador hace el resto. Sin código especial.

   Entonces, lo que debe hacerse para paquetes (de librería) es diferente (y no está reñido) con el caso más general de la librería compartida. Y de esto es lo que esta página trata.

   Desde el caso general de la librería compartida, una subdivisión puede distinguirse cuando tienen memorymgr compartida.

   Ten en cuenta que no puede haber un grupo de administradores de memoria en uso para esto, y varias unidades que funcionen compartiendo memoria. ESto es aplicable a casi cualquier gestor de memoria. Sin embargo, es lógico reservar el nombre de unidad sharemem para el gestor de memoria que es el más compatible para el trabajo entre procesos en la plataforma determinada (COM en Windows, cmem en Unix). Por lo tanto, estoy hablando del caso por defecto aquí, lo que no significa que otras personas no puedan hcerlo por su propia cuenta.

   Además, en el compilador (RTL) el soporte debe ser lo más universal posible, y funcionar también para las librerías que no son cargables, pero se cargan automáticamente al iniciar el ejecutable, y no requieren '"código manual", por ejemplo, de inicialización. Además, no debe interponerse en el camino de las soluciones "manuales" (como la referida), en otras palabras, debe ser reemplazable, ya que de otra manera el soporte del compilador (RTL) obstaculizaría el camino de lo que la gente construye por encima de la FPC.

   Sería útil sin embargo, si (SB) investigara si es posible usar los símbolos exportados del binario desde una librería cargada automáticamente (para los objetivos de nivel 1, Linux/FreeBSD - Windows - OS X). Esto porque así una librería tal vez podría, de hecho, conectarse en el binario madre.

   En breve, el primer objetivo es, simplemente, tener un esquema por defecto que funcione como el sharemem de Delphi para poner en la unidad "sharemem" .

   Lars dice: bueno, otra idea: en lugar de exportar el administrador de memoria del EXE, yo pensaba en hacer una fpsharemem.dll que exportara un único gestor de memoria fpc común en cada plataforma para uso de todos los programas y las DLL, en lugar de utilizar CMEM, es decir, todas las unidades pondrían fpsharemem.dll en su cláusula uses. De hecho, eso es realmente lo que la demo hace simplemente, en lugar de un fpsharemem.dll separado, es justo dentro de esa única DLL incluida en la demo y el resto del código, es decir, ¿por qué usar CMEM si podemos usar el gestor de memoria FreePascal? El gestor de memoría FreePascal está disponible en todas las plataformas, ¿no, siempre hay una dll FP para cada plataforma?

   He intentado responder a mis propias preguntas sobre la cuestión de la compatibilidad COM/IPC (comunicación entre procesos). Bueno de todos modos, sigue siendo un debate muy interesante. He tomado el camino de hacer una demostración para mostrar el concepto en la acción y para demostrar que ansistrings y tipos automatizado puede ser utilizados en una DLL normal de las de antes.

References

Contribuciones