Добрый день)
Кратко опишу, что есть:
Два класса: CSolver и CModel, а также обёртка для python
Обёртка:
// python_wrap.h
#include <Python.h>
#include <QDebug>
#include "cmodel.h"
extern CModel *gModel;
static PyObject *python_param(PyObject * self, PyObject* args){
try{
const char * name;
if(!PyArg_ParseTuple(args, "s", &name)){
return NULL;
}
double value = gModel->Parameter(name);
PyObject *obj = Py_BuildValue("d",value);
Py_IncRef(obj);
return obj;
}catch(...){
Py_RETURN_NAN;
}
}
static PyObject *python_result(PyObject * self, PyObject* args){
const char * name;
double output = 0.0;
try{
if(!PyArg_ParseTuple(args, "sd", &name,&output)){
return NULL;
}
gModel->setResult(name,value);
}catch(...){
Py_RETURN_NONE;
}
Py_RETURN_NONE;
}
static PyMethodDef SolverMethods[] = {
{"param",python_param, METH_VARARGS, ""},
{"result",python_param, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
CModel:
class CModel{
CModel(QString name);
~CModel()
bool Exec();
double Parameter(QString name);
void Final();
void setResult(QString name,double value);
double getResult(QString name);
private:
QMap<QString,double> mParameters;
QMap<QString,double> mResults;
}
//cmodel.cpp
CModel::CModel(QString name){
// Ищем в папке по названию модель и загружаем mParameters
Py_Initialize();
Py_InitModule("solver", SolverMethods);
}
CModel::~CModel(){
mParameters.clear();
if(Py_IsInitialized()){
Final();
}
}
void CModel::setResult(QString name,double value){
mResults.insert(name,value);
}
double CModel::getResult(QString name){
if(mResults.contains(name)){
return mResults[name];
}
return -1;
}
void CModel::Final(){
Py_Finalize();
}
bool CModel::Exec(){
int _resultRunning = 0;
mResults.clear();
try{
file = fopen(modelname, "r+");
if(file == NULL) return false;
_resultRunning = PyRun_SimpleFile(file,modelname);
if (_resultRunning != 0) return false;
}
return true;
}
double CModel::Parameter(QString name){
if(mParameters.contains(name)){
return mParameters[name];
}
return -1;
}
CSolver:
//csolver.h
extern CModel *gModel;
class CSolver{
CSolver();
~CSolver();
void Solve();
void Stop();
}
//csolver.cpp
CSolver::CSolver(){
gModel = new CModel(‘blah’)
}
void CSolver::Solve(){
while(true){
// Меняем параметры
if(!gModel->Exec()){
break;
}
qDebug() << gModel->getResult(‘aa’);
qDebug() << gModel->getResult(‘bb’);
}
}
}
void CSolver::Stop(){
gModel->Final();
}
Вопросы и проблемы
1) После выполнения Py_Finalize() - память не освобождается
2) Быстро съедается память, если скрипт на python становится громоздким, за 5 мин съедает до 1Гб.
3) Можно ли скомпилировать python скрипт и запускать только его?
4) Может стоит загнать содержимое файла в строку и её выполнять с помощью Py_SimpleString, но опять же проблема больших python скриптов
5) Может лучше есть способы обратиться к уже инициализируемому классу CModel?
Версия: Python 2.7.3