Ketema Harris wrote:
Hello, I am searching for help on getting some C code that deals with
Hilbert point mapping to work in PERL.  I have included the .c and .h file,
as well as the script that I am trying to get to work, and an equivalent
version in C++ that works fine.  I am slowing trying to read as much info as
I can on using c functions in PERL, but until such time as I can better
understand it, any help is much appreciated.

Thank you very much,
Ketema J. Harris



You want a perl script that replicates the following C++ script ??

#include <stdio.h>
#include <iostream>
#include "hilbert.h"

using namespace std;

int main()
{
        unsigned long Coord[3];
        hilbert_i2c(3,10,1086437,Coord);
        cout << Coord[2] << ',' << Coord[1] << ',' << Coord[0]<< endl;

        Coord[2] = 52.0;
        Coord[1] = 15.0;
        Coord[0] = 23.0;

        cout << hilbert_c2i(3,10,Coord) << endl;
return 0;
}

Coord is of type unsigned long ... yet you've assigned values to it (52.0, 15.0, 23.0) that appear to be doubles. I'll asume they're unsigned longs - if they should in fact be doubles then you'll need to replace some of the 'SvUV' with 'SvNV' and some of the 'newSVuv' with 'newSVnv' in the script below.
It looks to me that 'Coord' should be of type 'bitmask_t' (going by the function prototypes) - which, according to 'hilbert.h' is typedef'd to an unsigned long.


This script is untested (as I don't have libhilbert). Beware of typos and all sorts of other stupid errors.

use warnings;

use Inline C => Config =>
    LIBS => '-lhilbert',
    BUILD_NOISY => 1; # to make sure we get to
                      # see compiler warnings

use Inline C => <<'END_OF_C_CODE';

#include "hilbert.h"

void wrap_hilbert_i2c(SV * a, SV * b, SV * c) {
     Inline_Stack_Vars;
     bitmask_t coord[3], index;
     unsigned long nDims, nBits;

     nDims = (unsigned long)SvUV(a);
     nBits = (unsigned long)SvUV(b);
     index = (unsigned long)SvUV(c);

     hilbert_i2c(nDims, nBits, index, coord);

     Inline_Stack_Reset;
     Inline_Stack_Push(sv_2mortal(newSVuv(coord[0])));
     Inline_Stack_Push(sv_2mortal(newSVuv(coord[1])));
     Inline_Stack_Push(sv_2mortal(newSVuv(coord[2])));

     Inline_Stack_Done;
     Inline_Stack_Return(3);
}

SV * wrap_hilbert_c2i
     (SV * a, SV * b, SV * coord_0, SV * coord_1, SV * coord_2) {

     unsigned long nDims, nBits;
     bitmask_t ret, coord[3];

     nDims = (unsigned long)SvUV(a);
     nBits = (unsigned long)SvUV(b);

     coord[0] = (bitmask_t)SvUV(coord_0);
     coord[1] = (bitmask_t)SvUV(coord_1);
     coord[2] = (bitmask_t)SvUV(coord_2);

     ret = hilbert_c2i(nDims, nBits, coord);

     return newSVuv(ret);
}

END_OF_C_CODE

@coords = wrap_hilbert_i2c(3,10,1086437);
print "@coords\n";

@coords = (52, 15, 23);

print wrap_hilbert_c2i(3, 10, @coords), "\n";

__END__

Hope I've got that right (or close to it). Let me know if there's something not working that you can't fix.
Also take a look at 'perldoc Inline::C-Cookbook' and 'perldoc perlapi'.


Thanks for helping to fill in my evening :-)

Cheers,
Rob




Reply via email to