2008-12-14 10 views
14

Estoy buscando agregar la capacidad para que los usuarios escriban complementos para el programa que he desarrollado en Delphi. El programa es un ejecutable único sin archivos DLL.La mejor manera de agregar capacidad de complemento a un programa Delphi

Esto permitiría a la comunidad de usuarios escribir extensiones en mi programa para acceder a los datos internos y agregar capacidades que pueden ser útiles.

He visto la publicación en: Suggestions for Adding Plugin Capability? pero sus respuestas no parecen transferibles a un programa Delphi.

Me gustaría, si es posible, agregar esta capacidad y mantener mi aplicación como un solo ejecutable sin ningún DLL o módulos adicionales necesarios.

¿Conoce algún recurso, componente o artículo que sugiera la mejor manera de hacerlo en Delphi, o tiene su propia recomendación?

+0

Ver explicación adicional en mi respuesta – Serguzest

Respuesta

10

La primera pregunta que haría sería, ¿necesita los complementos para acceder a la interfaz de usuario de su aplicación de host, o agregar algún elemento de la interfaz de usuario propio? ¿O los complementos se limitarán a consultar y/o suministrar datos a su aplicación host?

Esto último es mucho más fácil y abre dos posibilidades. Otros ya han mencionado las DLL, que es la primera forma de hacerlo. Se aplican ciertas advertencias: en general, debe interactuar con un dll usando solo los tipos de datos que se usan en la API de Windows. De esta manera, puede estar seguro de que los archivos DLL de complemento comprenderán sus tipos de datos, sin importar en qué idioma/compilador se crearon (así, por ejemplo, use PChars, no cadenas. No pase, por regla general, clases Delphi como TStream a una DLL. Esto parecerá funcionar en algunos casos, pero no es seguro en general, porque incluso si la DLL se compiló en Delphi, puede haber sido una versión diferente del compilador, con una idea ligeramente diferente de lo que es TStream). Google para usar archivos DLL en Delphi, y encontrará muchos más consejos.

Otra forma que aún no se ha mencionado es habilitar los scripts en su aplicación. Hay varios motores de scripting de terceros muy capaces, tanto comerciales como gratuitos, y la mayoría de ellos le permiten intercambiar objetos Delphi con el script. Algunas de estas bibliotecas solo admiten Pascal como lenguaje de scripting, otras te permitirán usar Basic (quizás mejor para usuarios principiantes) u otros idiomas. Ver, por ejemplo, RemObjects Pascal Script (gratis) en http://www.remobjects.com/free.aspx.

Mi solución de scripting favorita en este momento es Python para Delphi (P4D, también gratis) de http://mmm-experts.com/Products.aspx?ProductID=3 Puede interactuar maravillosamente con sus clases a través de RTTI, y le permite ejecutar código Python en su aplicación Delphi, así como usar Delphi clases en scripts de Python. Dada la popularidad de Python, esta puede ser una solución viable si desea atraer desarrolladores a su proyecto. Sin embargo, cada usuario deberá tener una distribución de Python instalada.

Me parece que la barrera de entrada, desde el punto de vista de posibles escritores de plugins, es menor si usa scripts que si elige DLL.

Ahora, volviendo a mi pregunta inicial: las cosas se vuelven mucho más complicadas si necesita los complementos para interactuar con su interfaz de usuario, p. colocando controles en él. En general, las DLL no se pueden usar para hacer esto. La forma de Borland/CodeGear es utilizar paquetes (BPL). Con los BPL, puede acceder e instanciar las clases que ofrece un complemento como si estuvieran declaradas en su aplicación de host. El truco es que todos los BPL se deben compilar con la misma versión exacta y compilación de Delphi que su aplicación principal. En mi opinión, esto hace que los paquetes sean completamente poco prácticos, ya que es difícil esperar que todos los escritores de plugins potenciales de todo el mundo utilicen la misma versión de Delphi que eres. Una gran trampa.

Para evitar esto, he experimentado con un enfoque diferente: seguir usando DLL, y desarrollar una sintaxis para el plugin para describir la UI que necesita, luego crear la UI usted mismo en la aplicación de host. (XML es una forma conveniente de expresar la UI, ya que obtiene el concepto de parenting/nesting gratis). La sintaxis de la descripción de UI puede incluir devoluciones de llamada a la DLL activada cuando cambia el contenido o el estado del control. Sin embargo, este método restringirá los complementos al conjunto de controles de VCL que su aplicación ya usa o ha registrado. Y no es un trabajo de una noche, mientras que los BPL sí lo son.

Google para "Delphi plugin framework", también. Existen algunas soluciones listas para usar, pero hasta donde yo sé, generalmente usan BPL, con su utilidad limitada.

+0

+1. Muchos consejos muy buenos aquí. La creación de una interfaz de plug-in tiene muchas consecuencias, durante mucho tiempo, por lo que cuanto más se piense al respecto, mejor. – mghie

1

Puede echar un vistazo a Hydra de Remobjects. Esto no solo le permitirá agregar complementos, sino también mezclar win32 y .net.

2

Si los complementos se desarrollarán en el constructor Delphi o C++, use packages + interfaces. Delphi OTA es un buen ejemplo para eso. Si los complementos serán independientes del idioma, COM es una buena forma de hacerlo.

Adición: Si no va a usar COM, puede que necesite proporcionar SDK para cada idioma. Y el manejo de tipos de datos entre diferentes idiomas puede ser doloroso (por ejemplo, tipo de cadena delphi). El soporte COM de Delphi es excelente, no necesita preocuparse por el tipo de detalles. Esos son principalmente implícitos con el soporte COM de Delphi. No trates de inventar la rueda otra vez. Me sorprende por qué la gente no suele mencionar al respecto.

+0

No estoy familiarizado con lo que la OTA es Delphi, y una primera búsqueda Google no ayuda. ¿Tiene un buen enlace a un recurso que lo describe? – lkessler

+0

Delphi OTA: API de herramientas abiertas. Primer hit de Google: http://delphi.about.com/od/objectpascalide/a/wizardsexperts.htm –

+0

OTA = Abrir herramientas api. Proporciona muchas interfaces para usar las funciones de IDE en paquetes expertos o de tiempo de diseño.Por ejemplo, GExpert usa muchas funciones OTA. OTA no es un tipo de sistema de complemento genérico para los programadores de Delphi. Es específico para delphi IDE. Pensé que puede ser un buen ejemplo para ti. – Serguzest

9

Actualmente, the accepted answer to the question you cite es bastante apropiado para Delphi también. Sus complementos serán DLL, y puede dictar que deben exportar una función con un cierto nombre y firma. Luego, su programa cargará la DLL (con LoadLibrary) y obtendrá la dirección de la función (con GetProcAddress). Si el archivo DLL no se carga o la función no está allí, entonces el archivo DLL no es un complemento para su aplicación.

Después de que tenga la dirección de la DLL, puede llamarla. Puede pasar la función de una interfaz a algo que represente las partes de su aplicación que desea exponer. También puede requerir que la función devuelva una interfaz con los métodos que su aplicación llamará en diferentes momentos.

Al probar su sistema de complemento, será aconsejable escribir un complemento usted mismo con un idioma que no sea Delphi. De esta forma, puede estar más seguro de que no ha requerido inadvertidamente que todos usen Delphi.

+1

+1 en la sugerencia de que los complementos deben poder escribirse en otros idiomas además de Delphi. De lo contrario, es mucho más simple incluir en su aplicación el script de RemObjects Pascal y terminarlo. La creación de una interfaz para sus objetos internos es necesaria en ambos casos, ... – mghie

+0

y con las secuencias de comandos internas no tiene que invertir más trabajo para la propia interfaz del complemento. Además, asegúrese de que los complementos se puedan probar, agregar y eliminar sin la necesidad de cerrar su aplicación. – mghie

+0

"Puede pasarle a la función una interfaz para ..." ¿Cree que otros lenguajes pueden usar o implementar interfaces delphi sin COM? – Serguzest

4

Estoy usando complementos para implementar la mayor parte de la funcionalidad en el motor de juegos que estoy construyendo. El EXE principal se compone de un motor de script, un administrador de plug-in, algunas rutinas de gráficos básicos y no mucho más. Estoy usando TJvPluginManager de la biblioteca JEDI VCL. Es un administrador muy bueno y puede agregar casi todo lo que desee a su programa. Consulte las demostraciones incluidas con el paquete para ver cómo funciona. El único inconveniente es que agrega mucho código JCL/JVCL a su programa, pero eso no es realmente un problema si ya está utilizando otros componentes JVCL.

+0

¿TJvPluginManager limita los complementos a los escritos por Delphi? ¿Cómo se implementa la interfaz de todos modos, a través de COM? – mghie

+2

Sí, los complementos deben estar escritos en Delphi. (O tal vez C++ Builder. No estoy seguro). Los complementos deben ser descendidos de la clase base TJvPlugin, que básicamente es solo una envoltura alrededor de su funcionalidad de complemento para permitir que hable con el administrador. Y puede implementarlo como un DLL o un BPL. –

6

intenté hacer un overview of all such options hace algún tiempo. Junto con mis lectores/comentaristas, creamos esta lista:

  • DLL/BPL cargados desde el programa.
  • DLL/BPL cargado desde un sandbox (que podría ser otra copia del programa o una aplicación especializada de "servidor" y que se comunica con el programa principal a través de mensajes/sockets/msmq/named pipes/mailslots/memory mapped files).
  • COM (en cualquiera de sus variantes).
  • DDE (por favor, no).
  • Programa externo que se comunica a través de la entrada/salida estándar.
  • Programa externo que se comunica a través de archivos (el nombre del archivo es un parámetro del programa).
  • Programa externo que funciona a través de la carpeta desplegable (útil para el procesamiento por lotes).
  • Programa externo que se comunica con los mensajes de windows/sockets de windows/msmq/named pipes/mailslots/archivos mapeados de memoria/base de datos publish-subscribe.
4

El método más universal para agregar la capacidad del complemento es utilizar COM. Un buen libro para comenzar en el camino es Delphi Com Programming por Eric Harmon. Aunque originalmente se escribió para las versiones 3 a 5 de Delphi, los contenidos de los libros siguen siendo válidos con las últimas versiones de Delphi.

Personalmente, he usado esta técnica junto con scripts activos para permitir la personalización del usuario final.

7

Al principio fui para los complementos básicos de BPL y DLL. Y los encontró difíciles de mantener.

Si usa el sistema BPL, entonces debe hacer coincidir la versión BPL con la versión EXE. Esto incluye actualizaciones de Delphi que pueden romper algo. Descubrí (por las malas) que si necesito incluir todos mis complementos en cada versión, no tiene sentido tener complementos.

Luego cambié a los complementos DLL simples. Pero ese sistema solo complicó la base de código. Y eso no es algo bueno.

Mientras crusing la red encontré Lua lenguaje de script incrustado, y entregado con él. Lua es 150K DLL, integra un compilador de bytecode, un intérprete y un lenguaje de programación dinámico muy simple e inteligente.

Mis complementos son scripts simples de lua. Fácilmente mantaind y hecho. Hay ejemplos Delphi prefabricados, por lo que puede exportar cualquier clase o procedimiento como tabla o función Lua. GUI o no. Por ejemplo, tenía TurboPower Abbrevia en mi aplicación para comprimir. Exporté mi clase de compresión a lua, y ahora todos los complementos pueden llamar a zip ('.', 'dir.zip') y descomprimir(). Luego cambié a 7zip y solo implementé la clase anterior para usar 7zip. Todos los complementos funcionan como lo hicieron, con soporte para el nuevo zip ('.', 'dir.7z').

Hice TLuaAction que llama al procedimiento Execute(), Update(), Hint() desde su script.

Lua también tiene su propio sistema de complemento que hace que sea fácil agregarle funcionalidad. Por ejemplo, luacom make es fácil de usar. Automatización COM, luainterface permite llamar a .net desde lua. Ver luaforge para más. Hay Lua IDE hecho en Delphi, con fuente.

Cuestiones relacionadas