The C++ interface and the get_neigh method.

Hi OpenKIM folks,

I am writing a test in C++, and I am using the C++ interface to the KIM API.

In the C and Fortran interfaces, the kim pointer is passed explicitly to all API calls, but in the C++ interface the model it is an object with the API calls as methods.

What happens in the get_neigh call? Say the model is written in C or fortran, but the test is written in C++. The model calls the KIM_API_get_neigh(kimdl, …). That causes the registered get_neigh function of the test to be called. This function must have C linkage. But what it the kimdl object it gets passed (it has type void*)? Can it be safely cast to the C++ model object? I suspect not, so this function should probably use the C API rather than the C++ API? But if I have included the C++ API then the C API is not available. Is it OK to include both header files, or should I place the get_neigh function in a separate compilation unit? Or is the cast to the C++ object safe?

Best regards

Jakob

Hi Jakob,

Actually the cast can be done. Looking at how I implemented the interface in LAMMPS, it has the following get_neigh member function:

class PairKIM : public Pair {

    ...

    // static methods used as callbacks from KIM
    static int get_neigh(void** kimmdl, int* mode, int* request,
                         int* atom, int* numnei, int** nei1atom,
                         double** pRij);
};

int PairKIM::get_neigh(void **kimmdl,int *mode,int *request,
                        int *atom, int *numnei, int **nei1atom,
                        double **pRij)
{
    KIM_API_model *pkim = (KIM_API_model *) *kimmdl;

    int kimerror;
    PairKIM *self = (PairKIM *) pkim->get_test_buffer(&kimerror);

    ...
}

This may not be the cleanest way to organize all this (and I'll be making an effort to clean up as much of this type of thing as possible in a v2.0.0) but it works fine for now.

You can see, infact, that here we cast the kimmdl to a KIM_API_model pointer and then extract the test_buffer pointer and cast it to a PairKIM pointer. This all gives the get_neigh function simple access to the private internals of the PairKIM object through the "self" pointer....

As always, very happy to help.

Cheers,

Rya