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(...)

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".

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? 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. Maybe it has something to do with how C++ header files
work, but I thought that symbols are shared in the whole
program/library.

Thanks for any hints.

Ondrej

[0] http://docs.cython.org/docs/external_C_code.html#c-api-declarations
[1] http://github.com/certik/hermes_common
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to