2009-04-02 16 views
28

¿Cuáles son sus consejos para implementar un sistema de estilo de complemento?Implementación de un sistema de complemento en C o C++

+0

Relacionados - si no están duplicados - http://stackoverflow.com/questions/384121/creating-a-module-system-dynamic-loading-in-c – ChrisF

+0

Eche un vistazo a [este tutorial] (http: // sourcey.com/building-a-simple-cpp-cross-platform-plugin-system/). Han lanzado este tutorial como un proyecto multiplataforma de trabajo llamado [Pluga] (http://sourcey.com/pluga/) que utiliza una biblioteca llamada [LibSourcey] (https://github.com/sourcey/libsourcey). – aggregate1166877

Respuesta

29

En C (y creo que C++ también, aunque no lo he hecho yo mismo), esto se hace más típicamente utilizando módulos cargados dinámicamente. Las API: s para tales son dependientes de la plataforma.

En POSIX (Linux), utiliza la familia de funciones dlopen(). Básicamente construye su complemento por separado, luego lo carga en tiempo de ejecución, busca sus símbolos por su nombre y puede llamarlos.

Para Win32, hay LoadLibrary() que hace algo muy similar, construyes tu código en una DLL.

Para un práctico envoltorio que hace que todo esto sea fácil y transparente, consulte la API GModule de GLib.

+0

Para Win32, recomendaría LoadLibraryEx con el indicador LOAD_WITH_ALTERED_SEARCH_PATH establecido. – dalle

+0

esa es la forma en que lo hago. C++ no tiene un ABI definido, por lo que no puede usarlo de manera confiable para cargar clases de C++ de forma dinámica. mientras que c lo hace. Si necesita cargar C++, debe exponer todos sus módulos con una interfaz c (por ejemplo, COM lo hace mediante la exposición de 4 funciones) – gbjbaanb

+0

+1 solo para el enlace a GModule – drahnr

0

he tenido cierto éxito utilizando un sistema bastante ingenua:

  • Crear especificación API para plug-ins
  • utilizar un plug-in de gestor de
  • Uso LoadLibrary/GetProcAddress tiempo de ejecución basado en la vinculación dinámica Singleton
  • Implementar Inversion de evento basado en el control de la manipulación de notificar a los plug-ins
9

En el '9 2/'93 marco de tiempo trabajé en una arquitectura de complemento para Aldus PageMaker, que fue codificada en C++. PageMaker se creó en un marco de C++ OOP llamado VAMP, que ayudó a su portabilidad entre Mac OS y Windows.

Así que tratamos de usar las características de C++ para construir una arquitectura de complemento. Esto resultó ser muy problemático para las clases de C++ debido al llamado problema de clase de base frágil. Procedí a escribir un artículo que se publicó en revistas y que presenté en OOPSLA '93 en un taller de reflexión. También me puse en contacto con Bjarne Stroustrup en una conferencia de Usenix en Portland y procedí a dialogar con él durante varios meses, donde defendió el problema de lidiar con el problema de la clase base frágil en mi nombre. (Por desgracia, otros problemas se consideraron más importantes en ese momento).

Microsoft presentó el sistema COM/DCOM y para esa plataforma que se consideró como una solución viable al problema. C++ podría utilizarse como lenguaje de implementación para COM a través de clases abstractas utilizadas para definir interfaces COM.

Sin embargo, en la actualidad los desarrolladores se alejan de COM/DCOM.

Por el contrario, NeXT ideó una arquitectura de complemento utilizando Objective C a principios de los 90 en el marco NeXT Step. Hoy en día vive de forma vibrante en Mac OS X en las computadoras de Apple y en plataformas importantes como el iPhone.

presento el objetivo C habilitado para resolver el problema del complemento de una manera superior.

Personalmente, considero que el problema de la clase base quebradiza de C++ es su defecto más grave.

Si estaban construyendo una arquitectura plugin con la familia a base de C de las lenguas, sería hacerlo usando Objective C.

+0

¿Tiene un enlace a su artículo? O una referencia en alguna parte? – coryan

+0

la idea es que si cambia la clase base, puede romper todas las clases derivadas, sin embargo, creo que esto se aplica a todos los complementos oo. Ciertamente se aplica a jscript.net: http: //blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-frágil-base-classes.aspx – gbjbaanb

+1

Aquí una cita de uno de mis documentos: http://citeseerx.ist.psu.edu/viewdoc /summary?doi=10.1.1.51.418 debajo de la página hay una vista o enlace de descarga para obtener el .pdf: http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=1B865C7B3133C75949ECE12B20D3D140 ? doi = 10.1.1.51.418 & rep = rep1 & type = pdf – RogerV

3

Lo mejor es utilizar un marco como ACE (http://www.cs.wustl.edu/~schmidt/ACE.html) que protege (tan buena como sea posible) desde la codificación específica de la plataforma.

ACE contiene un marco de plugins que se basa en bibliotecas compartidas que puede usar para crear aplicaciones ensambladas dinámicamente.

Para una abstracción de mayor nivel, consulte CIAO (http://www.cs.wustl.edu/~schmidt/CIAO.html) la implementación de código abierto C++ del modelo de componentes CORBA.

5

Esto puede no ser lo que estás buscando, pero podrías incluir un lenguaje de scripting en tu aplicación, como Lua. Lua se diseñó para integrarse en otros programas y utilizarse como lenguaje de scripts para escribir complementos. Creo que es bastante fácil agregar el intérprete de Lua a su programa, aunque no conozco a Lua, por lo que no puedo garantizar la efectividad de una solución. Otros con más experiencia con Lua, por favor agregue comentarios sobre su experiencia con la incrustación de Lua en otra aplicación.

Esto, por supuesto, significa que sus complementos deben escribirse en Lua. Si no le gusta Lua, los intérpretes de de facto estándar de Perl, Python y Ruby están escritos en C y se pueden incrustar en un programa en C. Conozco una serie de programas que usan estos lenguajes como extensiones de lenguaje de scripting.

Sin embargo, no sé lo que estás buscando, ya que tu pregunta es un poco vaga. Tal vez sea apropiado más información sobre lo que quiere que las personas puedan hacer con dichos complementos. Para algunas tareas, un lenguaje de scripting completo puede ser un poco exagerado.

0

He escrito una biblioteca de complementos Pugg que carga clases de C++ a partir de archivos DLL y aquí está la lógica utilicé:

usuario exporta una función C de DLL que tiene un nombre único. Este nombre tiene que ser lo suficientemente único ya que las funciones no se pueden distinguir usando sus argumentos al cargar desde dlls.

La función C registra una o varias clases de fábrica llamadas "Controlador". Cada clase de controlador está asociada a una cadena. Cuando la aplicación principal desea crear una clase, reúne la clase de fábrica relacionada utilizando la cadena asociada. También implementé un sistema de verificación de versiones para no cargar plugins antiguos.

Dll la carga se realiza utilizando las funciones LoadLibraryA y GetProcAddress (Pugg actualmente funciona en Windows).

Una cosa que vale la pena mencionar es que la aplicación principal y las DLL deben compilarse usando el mismo compilador y utilizando las mismas opciones de compilación (modos de liberación/depuración, configuración de optimización, versiones stl, etc.). De lo contrario, podría haber problemas con la asignación de clases.

10

La mejor plataforma y asesoramiento independiente del idioma que puedo dar es la siguiente:

diseño completo su aplicación en todo el SDK de plugins.

IMO, un SDK de complemento no debe ser una idea de último momento. Si el diseño de su aplicación para ser básicamente una cáscara vacía que carga los plugins, a continuación, las principales características se implementan en su propio SDK, se obtienen los siguientes beneficios:

  • alta modularidad de los componentes, y la separación clara del propósito (se clase de las fuerzas de su arquitectura para ser bueno)
  • obliga a su SDK para ser realmente bueno
  • permite que otros desarrolladores de terceras partes para hacer extremadamente potente, de nivel central características, así
  • Los nuevos desarrolladores/empleados pueden iniciar trabajar en una nueva característica importante sin tener que tocar la aplicación principal; pueden hacer todo su trabajo en un complemento (que respiraderos ellos atornillar cualquier otra cosa)

En C/C++, es probable que utilice las bibliotecas de vínculos dinámicos y, o bien los punteros de función (C) o interfaces (clases consistente únicamente en métodos virtuales puros, para C++). Sin embargo, incluso si usa Javascript, aún recomendaría la arquitectura anterior.

2

He escrito un artículo sobre cómo implementar un sistema de complemento utilizando bibliotecas de enlace dinámico. El artículo está escrito desde el punto de vista de un programador de Windows, pero la técnica se puede aplicar a un entorno de tipo Linux/Unix.

El artículo se puede encontrar aquí: http://3dgep.com/?p=1759

El punto principal es, usted debe crear un archivo DLL "común" que está vinculado de manera implícita por tanto la aplicación principal (la aplicación principal) y por las implementaciones del plugin. A continuación, la aplicación central puede vincular y cargar dinámicamente los complementos en tiempo de ejecución.

El artículo también muestra cómo puede compartir de forma segura la instancia estática (singleton) de una clase en varias DLL mediante el uso de la DLL "común".

El artículo también muestra cómo puede exportar una función "C" o variables desde una DLL y usar las funciones exportadas en la aplicación en tiempo de ejecución.