[Rd] using openbabel plugins in R

Kevin Horan khoran at cs.ucr.edu
Mon Mar 25 20:50:35 CET 2013


I posted this in openbabel-devel but didn't get much help, so hopefully 
someone here can help. I don't think its too openbabel specific.

I would like to make use of open babel from within the R language.
Initially I just need to do some format conversions, but may expand the
usage to other parts of OpenBabel as well. I am familiar with embedding
C/C++ code in R, but I'm having some trouble with the plugin mechanism
of OpenBabel in this case. The  problem is that the formats are not
available when I run the OpenBabel code from within R. So, for example,
if I search for the SDF format like so:
      OBFormat *format = conv.FindFormat("SDF");
I always get back a 0 value. The same chunk of code executed outside of
R, as a normal stand-alone program, works fine. So does anyone know how
I can ensure that the formats get loaded? Thanks.
      One other thing to mention, someone might suggest linking against a
static version of openbabel which includes all the plugins. I would like
to avoid that if possible since this needs to work in an R package that
will be distributed across platforms, so it would be hard to ask people
to compile a special, static, version of openbabel just to compile this
R package. Since it needs to work on windows, mac and linux, it would be
nice  if I can make use of any existing installed shared obenbabel
libraries. If it turns out it can't be done, then I'll go down that
path. Thanks.

      Here is an example of the problem:

test program (obtest2.cc):

     #include <iostream>
     #include <openbabel/obconversion.h>
     #include <R.h>
     #include <Rinternals.h>

     extern "C" {   SEXP test(); }

     int main(){
         test();
     }
     SEXP  test()
     {
         OpenBabel::OBConversion conv;
         OpenBabel::OBFormat *format = conv.FindFormat("SDF");   //    
search for SDF format
         std::cout<<"format: "<<format<<std::endl;        // print out 
search result, either 0   or an address
         return R_NilValue;
     }


compile:
      g++  -I/usr/include/openbabel-2.0 -I/usr/share/R/include -fpic -c 
obtest2.cc -o obtest2.o
      g++ -o obtest2 obtest2.o -fpic  -lopenbabel 
-lR                       # Executable
      g++ -shared -o libobtest2.so obtest2.o -fpic  -lopenbabel -lR  # R 
library

Run executable:
      $ ./obtest2
      format: 0x7f1858275d20  #found some result, this is what I expect

Run in R:
      R>dyn.load("libobtest2.so")
      R>.Call("test")
          format: 0              # the format was not found, so 0 was
returned
          NULL


After some more experimentation, I have discovered I can get it to work 
in the following way, but I think it is a bit impractical. If I compile 
the shared library as:
     g++ -shared -o libobtest2.so obtest2.o -fpic 
/usr/lib/openbabel/2.2.3/mdlformat.so -lopenbabel -lR
so the name of one of the plugins is specified. Then, in R I run:

     R>dyn.load("/usr/lib/openbabel/2.2.3/mdlformat.so")
     R>dyn.load("libobtest2.so")
     R>.Call("test")
         format: 0x7fe114c96d20
         NULL
So then it works. But this requires that I know the full path to every 
plugin when the code is compiled and when the library is loaded. Is 
there a practical way to do this, say, if this were part of an R 
package? I have also tried compiling the shared library as before, 
without the plugin, and then just loading the plugin with dyn.load but 
this does not work. It seems like it should though, does anyone know why 
it doesn't? Conversely, if you compile with the plugin specified, but 
don't load it with dyn.load it seg faults.
     The way it works normally in OpenBabel is that each plugin is its 
own shared library and then they get loaded at run time with the dlopen 
function (on linux at least). I have verified that this code is still 
being executed when called from within R, but it doesn't work for some 
reason.
     Also, swig does not help.

Thanks.

Kevin



More information about the R-devel mailing list