2012-03-02 8 views
5

Tengo un programa de simulación que repite un conjunto de funciones en un orden específico una gran cantidad de veces y luego muestra el resultado de algunos cálculos basados ​​en esas funciones. Cada función mutará un objeto Simulator de alguna manera y tomará una cantidad variable de argumentos de diferentes tipos. Por ejemplo:¿La mejor manera para que un programa C++ siga un script definido por el usuario?

class Simulator 
{ 
    Simulator(); 
    void A(int x, double y, string z); 
    void B(int x, int y); 
    void C(double x); 
}; 

Quiero que el usuario sea capaz de especificar el orden en que serán llamados estas funciones, así como los argumentos, y tengo que ser capaz de almacenar esta información en una especie de guión para el programa a seguir. Por ejemplo, un script podría llegar a ser traducido a las siguientes acciones para el programa:

Simulator mySim; 
mySim.A(5, 6.0, "a string"); 
mySim.B(1, 1); 
mySim.A(3, 4.0, "another string"); 
mySim.C(10.0); 

¿Existe una manera eficiente de hacerlo? Mi pensamiento inicial es tener una lista vinculada de objetos, cada uno de los cuales almacena el nombre de la función, así como los argumentos. El programa luego atravesaría la lista, llamando a cada función por turno. Sin embargo, esto plantea un par de problemas:

(a) Cómo almacenar los argumentos en la lista, que serán diferentes para cada función (tanto en cantidad como en tipo).

(b) Parece bastante ineficiente ya que mi programa tendrá que ejecutar una serie de sentencias if en cada ejecución de la simulación, para determinar a qué funciones llamar.

¿Alguien tiene alguna sugerencia?

Respuesta

6

Mi sugerencia: no inventar su propio lenguaje de scripts/intérprete.

Si desea comenzar rápidamente a admitir scripts definidos por el usuario en un solo día, consulte Lua. Podría decirse que es uno de los idiomas más fáciles de integrar en un programa C/C++. Con luabind, es aún más fácil:

module(L) 
[ 
    class<Simulator>("Simulator") 
     .def("A", &Simulator::A) 
     .def("B", &Simulator::B) 
     .def("C", &Simulator::C) 
]; 

¡Hecho! Ahora puedo ejecutar guiones lua que pueden crear simuladores y funciones de llamada y obtener todas las características del lenguaje lua completo y sus bibliotecas base, calcular expresiones matemáticas con cada llamada, crear funciones definidas por el usuario, cierres, lambdas, etc. lua es un demonio de velocidad cuando se trata de lenguajes de scripting.

En realidad, logré convertir un programa comercial de C++ a gran escala en uno totalmente programable con Lua en un solo día. Es muy fácil de insertar, ya que es para lo que fue diseñado.

También hay Python que es bastante similar a luabind si utilizamos Boost.Python aunque es mucho más doloroso con la API C y un poco más tedioso para empezar (no podemos simplemente construir una biblioteca estáticamente vinculada e ir y hay muchas variables de entorno con las que tenemos que lidiar, como sys.path, y nos aseguramos de usar la implementación de Python correcta para las versiones de depuración/versión).

También puede elegir entre otros idiomas, pero esos dos de los más populares que conozco proporcionan bibliotecas de C++ para facilitar la unión.

También podría ir con SWIG y admitir múltiples lenguajes de scripting de fábrica, pero SWIG tarda bastante tiempo en aprender ya que tiene una gran cantidad de documentación con muchos detalles que debe prestar atención ya que funciona para muchos diferentes idiomas.

+0

Gracias. Analizaré LUA, ya que eso parece más apropiado para mis requisitos, ya que solo estoy buscando implementar scripts muy simples. – JBentley

+0

@JonBentley Creo que harás un largo camino. Además de ser capaz de integrar el soporte de lua con tanta facilidad, aprender cómo admitir un lenguaje de scripting embebido de propósito general en sus aplicaciones puede abrir un mundo completamente nuevo de programación híbrida de C++/script para todos sus proyectos futuros. – stinky472

Cuestiones relacionadas