2010-05-07 13 views
6

He escrito un código de simulación de física en C++ y el análisis de los archivos de texto de entrada es un cuello de botella. Como uno de los parámetros de entrada, el usuario debe especificar una función matemática que se evaluará muchas veces en tiempo de ejecución. El código C++ tiene algunas clases de funciones predefinidas para esto (en realidad son bastante complejas en el aspecto matemático) y algunas capacidades de análisis limitadas, pero no estoy satisfecho con esta construcción en absoluto.¿Pasar el objeto C++ al código C++ a través de Python?

Lo que necesito es que tanto el algoritmo como la evaluación de la función permanezcan rápidos, por lo que es ventajoso mantenerlos como código compilado (y, preferiblemente, las funciones matemáticas como objetos de función C++). Sin embargo, pensé en pegar toda la simulación con Python: el usuario podía especificar los parámetros de entrada en un script de Python, al tiempo que implementaba el almacenamiento, la visualización de los resultados (matplotlib) y la GUI también en Python.

Sé que la mayoría de las veces, la exposición de las clases de C++ se puede hacer, p. con SWIG pero todavía tengo una pregunta sobre el análisis de la función matemática definida por el usuario en Python:

¿Es posible de alguna manera construir un objeto de función C++ en Python y pasarlo al algoritmo C++? P. ej. cuando llamo

f = WrappedCPPGaussianFunctionClass(sigma=0.5) 
WrappedCPPAlgorithm(f) 

en Python, sería devolver un puntero a un objeto de C++ que luego se pasa a una rutina de C++ que requiere un puntero tal, o algo similar ... (no me pregunte acerca de la memoria gestión en este caso, sin embargo: S)

el punto es que no devolución de llamada debe hacerse a Python código en el algoritmo. Más adelante me gustaría extender este ejemplo para hacer también algunos análisis de expresiones simples en el lado de Python, como la suma o el producto de las funciones, y devolver algún compuesto, árbol de análisis como el objeto C++, pero vamos a mantenernos en lo básico por ahora.

Perdón por las publicaciones largas y por las sugerencias con anticipación.

Respuesta

3

Hago cosas similares a esto todo el tiempo. La solución más simple, y la que suelo elegir porque, en todo caso, soy flojo, es aplanar tu API a una API similar a C y luego simplemente pasar punteros hacia y desde Python (o tu otro idioma de elección).

En primer lugar crear sus clases

class MyFunctionClass 
{ 
    public: 
    MyFunctionClass(int Param) 
    ... 
}; 

class MyAlgorithmClass 
{ 
    public: 
    MyAlgorithmClass(myfunctionclass& Func) 
    ... 
}; 

continuación, crear una API C-estilo de las funciones que crea y destruye esas clases. Usualmente salgo para pasar el vacío * porque los idiomas que uso no mantienen la seguridad del tipo de todos modos. Es más fácil de esa manera. Sólo asegúrese de echar de nuevo al tipo correcto antes de que realmente utiliza el vacío *

void* CreateFunction(int Param) 
    { 
     return new MyFunctionClass(Param); 
    } 

    void DeleteFunction(void* pFunc) 
    { 
     if (pFunc) 
      delete (MyFunctionClass*)pFunc; 
    } 

    void* CreateAlgorithm(void* pFunc) 
    { 
     return new MyAlgorithmClass(*(MyFunctionClass*)pFunc) 
    } 

    void DelteAlgorithm(void* pAlg) 
    { 
     if (pAlg) 
      delete (MyAlgorithmClass*)pAlg; 
    } 

No todo lo que tiene que hacer es hacer pitón llamada función de los C-estilo. De hecho, pueden (y probablemente deberían) ser funciones "c" externas para hacer que la vinculación sea mucho más fácil.

Cuestiones relacionadas