On Wed, Mar 3, 2010 at 1:55 PM, Lisandro Dalcin <[email protected]> wrote: > 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)
Ah --- that explains everything. I am still learning C++. :) > >> 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. In this case, that'd be cool. It'd be a bit tedious to repeat all the functions in the Python class, but maybe I'll figure out some shortcut. > >> 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" :-) ... Got it --- everything is clear now. > > 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... Do you have some ideas how Cython could be improved to make my use case easier? I can try to write something too --- I am still in the stage of figuring things out, not sure yet what I really want in details. I only know my general goal --- it should be easy for C++ users to use it, should be robust (no segfaults) and Python internals should not be visible at all. I am half way there already. Thanks for the help, Ondrej _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
