deadpickle has asked for the wisdom of the Perl Monks concerning the following question:

I would really like to use this library. It reads in 88D L2 radar data and gets all the part that I think I will need to display the data in a GTK2 window (Using goo). The problem is its in C. I dont know C. So this is where the monks come in. I would like to use this library because it seems like the only choice to perform this kind of task. So, how can I do this? can I link a C library to Perl code somehow? Also, is there a simple way to wrap the C code so that I can call it from perl? Maybe using SWIG? I really have no clue, and when you have no clue, ask someone who might. Thanks.

Replies are listed 'Best First'.
Re: Wrapping a C library
by ig (Vicar) on Mar 13, 2009 at 04:57 UTC

    You can link C libraries with perl.

    Two options you should consider are perlxs and Inline::C.

    You can find examples of both being used in various CPAN modules.

    Update: PM has a tutorial on Inline::C.

Re: Wrapping a C library
by syphilis (Archbishop) on Mar 13, 2009 at 07:47 UTC
    Maybe using SWIG?

    That's definitely an option. That's how the Math::GSL source is created. (Math::GSL wraps the GSL library.)
    However, I don't know how SWIG works, or how to use it.
    Inline::C (already mentioned) also has an 'AUTOWRAP' capability which could presumably be utilised. Although I've used Inline::C extensively, I don't know how to make proper use of 'AUTOWRAP' either. Of course, you can always craft the wrapping by hand using Inline::C or XS. That's the way I've always done it - it's a bit laborious, but at least you don't have to come to terms with the use of AUTOWRAP :-)

    If you do use Inline::C, be sure to check out 'perldoc Inline::C-Cookbook'. It has some good examples that will show you how to link an external library, and how to create a "radar*" object - among other things.

    Note that Inline::C and XS are essentially the same. Inline::C just takes its input in the form of C code, autogenerates the XS code from that C code, and then automatically compiles the XS code and runs the perl code (which presumably makes use of that compiled XS code). It's not hard to take the Inline::C code and convert it to an XS file if you ever want to.

    Cheers,
    Rob
Re: Wrapping a C library
by szbalint (Friar) on Mar 14, 2009 at 01:18 UTC

    If I want to be entirely honest with you, to use a C library from Perl, you either need someone to write the glue for you, or write it yourself. The problem is that perlxs is basically rock-climbing in the sense that no pure Perl code prepares you for it, there is no ramp.

    First, you need to know C. This is the easy part. The hard part is perlxs, since it requires a basic level of understanding of the perl internals. perl core is full of macroes (and it's not necessarily a bad thing) and you need to know a sizeable chunk of it to begin. It's not easy.

    I have to confess that even though I maintain a XS Perl module, my understanding of the core is basic. To gain familiarity with perl core seemed to me like learning a new language.

Re: Wrapping a C library
by ig (Vicar) on Mar 14, 2009 at 09:48 UTC

    As a tease for Inline::C, the following is from the start of the library's documentation. It gets as far as telling me the library doesn't recognize the file type. In a quick search I couldn't find a compatible data file for download.

    #!/usr/bin/perl # use Inline C => DATA => INC => '-I/usr/local/trmm/GVBOX/include' => LIBS => '-L/usr/local/trmm/GVBOX/lib -lrsl'; my_test(); __END__ __C__ #include "rsl.h" int my_test() { Radar *radar; radar = RSL_anyformat_to_radar("radar.dat", NULL); RSL_load_refl_color_table(); RSL_volume_to_gif(radar->v[DZ_INDEX], "dz_sweep", 400, 400, 200.0) +; return(0); }

    If someone posts a link to a compatible data file I would poke at it some more.

      I had no idea you were going to do this so I'm sorry for a late response. I can get you a data source here: Level3 or Level2

      I see you used the library installed on linux. I would like to use this library under windows, can inline::c use just the C files? Is there a way I can do this in windows?

        I would like to use this library under windows

        If you have the library on windows, then you can use it with Inline::C in the same way as ig used it on linux. Is there a Windows version of this library available ? The source wouldn't compile for me (on Windows) due to (at least) one missing header file - and I didn't persevere with trying to find a workaround.

        can inline::c use just the C files?

        You could probably use just the C files with Inline::C - but you'd still need to overcome that problem of the missing header(s), and it's much simpler, imo, to use the library anyway.

        Cheers,
        Rob

        This can be done on Windows, but I don't have a Windows build environment myself. I'm sure others here can tell you what you will need to support Inline::C or XS (the former is just an interface to the latter) on Windows.

        The following slightly modified script produces a set of gif files given a data file and a site ID as arguments. So, not surprisingly, the library can be called from Perl on Linux platform quite easily.

        Regarding using the library on Windows, note the following from the GVBOX page - http://trmm-fc.gsfc.nasa.gov/trmm_gv/software/gvbox/gvbox.html:

        It is assumed that you have a working Unix operating system and that you can compile C, C++ and Fortran source code, and that you have perl and optionally bison and flex.

        I can't find any evidence that it has been ported to Windows - which doesn't mean that it hasn't been or that it would be difficult to do.

        #!/usr/bin/perl # use Inline C => DATA => INC => '-I/usr/local/trmm/GVBOX/include' => LIBS => '-L/usr/local/trmm/GVBOX/lib -lrsl'; my $file = shift or die "USAGE: radar.pl file ID\n"; my $id = shift or die "USAGE: radar.pl file ID\n"; my_test($file, $id); __END__ __C__ #include "rsl.h" int my_test(char* file, char* id) { Radar *radar; radar = RSL_anyformat_to_radar(file, id); RSL_load_refl_color_table(); RSL_volume_to_gif(radar->v[DZ_INDEX], "dz_sweep", 400, 400, 200.0) +; return(0); }
Re: Wrapping a C library
by kingkongrevenge (Scribe) on Mar 13, 2009 at 22:51 UTC
    You probably want to try h2xs.

    The page you link to says the library is object oriented C. This means it's probably not trivial to meaningful wrap its semantics for use in perl in a natural way.

    You're going to have to learn some C if you want to do this. You're going to have to learn how to use either perlxs or SWIG.