On 3 March 2010 17:22, Ondrej Certik <[email protected]> wrote: > Hi, > > I am using the C API Declarations[0], which generate the file > _hermes_common_api.h, that I include in my C++ files. I am having > problems with initializing the module properly. > > Here is an example of my C++ function, that internally calls scipy's > sparse solver to solve the system: > > void solve_linear_system_scipy_cg(CooMatrix *mat, double *res) > { > if (import__hermes_common()) > throw std::runtime_error("hermes_common failed to import."); > CSRMatrix M(mat); > insert_object("m", c2py_CSRMatrix(&M)); > insert_object("rhs", c2numpy_double_inplace(res, mat->get_size())); > cmd("A = m.to_scipy_csr()"); > cmd("from scipy.sparse.linalg import cg"); > cmd("x, res = cg(A, rhs)"); > double *x; > int n; > numpy2c_double_inplace(get_object("x"), &x, &n); > memcpy(res, x, n*sizeof(double)); > } > > the functions insert_object(), cmd(), c2numpy_double_inplace() etc. > are declared in my .pyx file to ease C++ and Python integration (the > whole code is at [1]). Everything works, as long as I call the > "import__hermes_common()" function. Since I call Python things all > over my C++ code, it's kind of annoying to always call this by hand. > Also, doesn't it slow things down? > > What is the best way to do this? > > It occurred to me that I could create a "Python" C++ class, whose > constructor would import the module if needed, and it would be used > like this: > > Python p; > p.insert_object(...) > p.cmd(...) > p.get_object(...) >
That's the way I would do it... Moreover, all C++ -- Python interactions should go via this object, so you should wrap the C API calls of your module as methos of the "Python" class. > Another annoying thing is that I currently need to have the following > at the beginning of my C++ main() function: > > // This is a hack, this should be set somewhere else: > putenv((char *)"PYTHONPATH=../.."); > Py_Initialize(); > PySys_SetArgv(argc, argv); > > I would like this to be handled automatically somehow, probably in the > constructor of the C++ class "Python". > Yep.. > The problem that I am having is that it seems to me, that I need to > call import__hermes_common() in every single .cpp file that I have, > even though that I link all of them into a shared library. It > segfaults if I don't do it. This confuses me. Here is a part of the > code in _hermes_common_api.h: > > static PyObject *(*c2py_CooMatrix)(struct CooMatrix *); > static PyObject *(*c2py_CSRMatrix)(struct CSRMatrix *); > static void (*cmd)(const char*); > static void (*set_verbose_cmd)(int); > static void (*insert_object)(const char*, PyObject *); > > those have to be initalized by calling import__hermes_common(), that > is clear, but why isn't it enough to call it once per the > project/shared lib? Because these are "static" ... and these are not visible outside compilation units (i.e. outside each C source) > I call it in matrix.cpp, but if I don't call it in > python_solvers.cpp as well, it seems it won't get initialized and it > segfaults. Of course. Each source has it's own copy of these pointers, then you have to init them at each source... Again, if you route stuff using an globally accessible instance of a "Python" class, this is no longer an issue. > Maybe it has something to do with how C++ header files > work, but I thought that symbols are shared in the whole > program/library. > Yes. Symbols are shared, as long as then are not "static" :-) ... Cython could grow support for your use case... If you really feel you will need this (as opposed to implementing the "Python" class), perhaps I could take a look at it and implement something... -- Lisandro Dalcin --------------- Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC) Instituto de Desarrollo Tecnológico para la Industria Química (INTEC) Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET) PTLC - Güemes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594 _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
