2008-09-04 15 views
44

Los sistemas de complemento en C++ son difíciles porque el ABI no está definido correctamente, y cada compilador (o versión del mismo) sigue sus propias reglas. Sin embargo, COM en Windows muestra que es posible crear un sistema de complemento mínimo que permita a los programadores con diferentes compiladores crear complementos para una aplicación host utilizando una interfaz simple.¿Qué es seguro para un sistema de complemento C++?

Seamos prácticos, y dejemos el estándar C++, que no es muy útil a este respecto, aparte de un minuto. Si quiero escribir una aplicación para Windows y Mac (y opcionalmente Linux) que admita plug-ins de C++, y si quiero dar a los autores de plug-in una amplia selección de compiladores (digamos versiones de Visual C++ de menos de 2 años) , GCC o el compilador C++ de Intel), ¿con qué características de C++ podría contar?

Por supuesto, supongo que los complementos se escribirán para una plataforma específica.

De la parte superior de mi cabeza, aquí están algunas de las características de C++ que se me ocurren, con lo que creo que es la respuesta:

  • disposición vtable, utilizar objetos a través de las clases abstractas? (sí)
  • tipos incorporados, punteros? (sí)
  • ¿estructuras, uniones? (sí)
  • ¿excepciones? (no)
  • funciones "C" externas? (sí)
  • stdcall funciones "C" no externas con tipos de parámetros incorporados? (sí)
  • no stdcall no-extern Funciones "C" con tipos de parámetros definidos por el usuario? (no)

Agradeceré cualquier experiencia que tenga en esa área que pueda compartir. Si conoce alguna aplicación moderadamente exitosa que tenga un sistema de complemento C++, también es genial.

Diario Carl

Respuesta

25

Dr. Dobb de Building Your Own Plugin Framework: Part 1 tiene un artículo que es bastante buena lectura sobre el tema. Es el comienzo de una serie de artículos que cubre la arquitectura, el desarrollo y la implementación de un marco de plugin multiplataforma de C/C++.

+3

Esta respuesta sería mejor si hiciera que el enlace "Aquí" fuera un poco más descriptivo. En este momento, no puedes decir a qué estás vinculando. –

+1

¡Gracias por el consejo!Punto tomado – Serge

1

Tengo mi propio motor de juego que tiene un sistema de plug-in C++.

Tengo un código en los archivos de encabezado por lo que se pone en la unidad de compilación del complemento.

Las funciones más grandes que residen en el motor principal se llaman mediante una función C exportada (el complemento llama a MyObject_somefunction (MyObject * obj) que en el motor simplemente llama a obj-> somefunction()). Si llama a una función C es feo para su gusto, a continuación, con un poco de engaño cabecera, cuando el encabezado está incluido en el plugin, tienen la función de miembro #defined para llamar a la función C:

#if defined(IN_THE_PLUGIN) 
void MyObject::somefunction() { MyObject_somefunction(this); } 
#endif 

funciones virtuales o bien tienen que ser puro o el código vive en el archivo de encabezado. Si no estoy heredando de una clase y simplemente instalando una, el código de función virtual puede vivir en el motor, pero luego la clase debe exportar algunas funciones C para crear y destruir el objeto que se llama desde el complemento.

Básicamente, los trucos que he usado, con el objetivo de mantener la independencia total de la plataforma, solo ascienden a las exportaciones de C y los trucos del archivo de encabezado.

6

Es posible que también desee considerar la sustitución de la interfaz del complemento convencional por una interfaz de scripting. Hay algunos enlaces muy buenos para varios lenguajes de scripting en C/C++ que ya han resuelto su problema. Puede que no sea una mala idea construir sobre ellos. Por ejemplo, eche un vistazo a Boost.Python.

+0

Si piensa en eso, diría que Lua está mucho mejor, ya que es mucho más fácil de integrar con C++ y es mucho más liviano. –

+1

Dicho esto, en algunas ocasiones las secuencias de comandos simplemente no son suficientes, especialmente si desea permitir complementos que tengan acceso al sistema operativo. –

3

creo que está a salvo la creación de un sistema de plugins basados ​​en:

  • Embalaje de la funcionalidad plug-in en la biblioteca (.dll, .so, etc.)
  • Requerir que el plugin exponer C-lenguaje clave exportaciones.
  • Exigir que el complemento implemente (y devuelva un puntero/referencia) una interfaz abstracta de C++.

Probablemente el sistema de plugins C++ más exitoso: bueno viejo Adobe Photoshop. Y si no es así, uno de los formatos virtuales de sintetizador como VSTi, etc.

3

El libro Imperfect C++ by Matthew Wilson tiene una buena información sobre esto.

El consejo en el parece ser: siempre que use el mismo compilador (o equivelant), puede usar C++, de lo contrario, es mejor usar C como una interfaz encima de su código C++.

+0

Gracias por el consejo. Me he topado con ese título tantas veces que lo compré esta vez. –

5

Qt tiene un sistema muy agradable para complementos que he usado en el pasado. Utiliza el sistema de metaobjetos de Qt para superar muchos de los problemas que suelen encontrarse al intentar desarrollar complementos de C++.

Un ejemplo es cómo funciona Q_DECLARE_INTERFACE, para evitar que utilice un complemento incompatible. Otro es el build key, para asegurarse de cargar el plugin correcto para su arquitectura, sistema operativo, compilador. Si no usas el sistema de complementos de Qt, estas son cosas de las que tendrás que preocuparte e inventar soluciones por ti mismo. No es necesariamente ciencia de cohetes, y no estoy diciendo que fallarías, pero los chicos de Trolltech son bastante inteligentes y han pasado un tiempo pensando en ello, y prefiero usar lo que crearon que reinventar la rueda yo mismo. .

Otro ejemplo es que RTTI generalmente no funciona entre los límites de DLL, pero cuando se utiliza Qt, cosas como qobject_cast que dependen del sistema de metaobjetos funcionan a través de los límites de DLL.

Cuestiones relacionadas