in reply to Re: Need Help with perlxstut
in thread Need Help with perlxstut
The script chugs along, then errors out on the compile with the following:@Coord[3]; hilbert_i2c(3,10,190355,@Coord); print join(" ",@Coord); @Coord[2] = 35.5; @Coord[1] = 40; @Coord[0] = 36.8; print hilbert_c2i(3,10,@Coord), "\n"; use Inline C => Config => LIBS => '-lhilbert'; use Inline C => <<'END_OF_C_CODE'; Lots of C code Here with the above functions implemented END_OF_C_CODE
"Can't locate auto/main/hilbert_i2c.al in @INC" being the most relevant part obviously, but I am at a loss as to where the proper files should be. The hilbert.c file is in the inline portion of the perl script, and the Hilbert.h files is in the same directory. Where else should it go?E:\Profiles\ADMINI~1.TEM\MYDOCU~1\VISUAL~1\MACHIN~1>perl Hilbertknn.pl Can't locate auto/main/hilbert_i2c.al in @INC (@INC contains: E:\Profi +les\ADMINI ~1.TEM\MYDOCU~1\VISUAL~1\MACHIN~1\_Inline\lib E:/Perl/lib E:/Perl/site +/lib .) at Hilbertknn.pl line 2
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Need Help with perlxstut
by tachyon (Chancellor) on Sep 28, 2004 at 01:08 UTC | |
When you say it chugs along what you mean is that it fails to compile. For a start your calling syntax is just not going to work. Next your knowledge of C seems imperfect. A library is compiled binary code. To use it you need the headers and the library. You don't have that, you have the C headers and main source code. If you are goind to inline it you need the headers and then the main source inline. When you want to link C code into Perl the main issue is basically type conversion, from the perl SV, AV or HV types, into C types and then back again. The main advantage of Inline::C is it will handle some simple type conversions for you automatically, but it only handles really simple ones. With XS you are expected to do it yourself. Your error will probably be typemap/conversion related. You will also need to pass an array ref of your N dimensional coordinates and decant the values in your C. See Re: Using c executable in Perl Script for an example of how to do that. cheers tachyon | [reply] |
by ketema (Scribe) on Sep 28, 2004 at 13:16 UTC | |
| [reply] [d/l] |
by tachyon (Chancellor) on Sep 28, 2004 at 23:23 UTC | |
You don't seem to understand that a long is an INTEGER type, so can't hold a float.
Uncomment the non_existant_function and you will generate the .al error - it can't autoload the non existant function. cheers tachyon | [reply] [d/l] |
by ketema (Scribe) on Sep 28, 2004 at 14:13 UTC | |
C:\HilbertPL>perl -MInline=info HilbertPL.pl <-----------------------Information Section-----------------------------------> Information about the processing of your Inline C code: Your module is already compiled. It is located at: C:\HilbertPL\_Inline\lib\auto\HilbertPL_pl_301c\HilbertPL_pl_301c.dll The following Inline C function(s) have been successfully bound to Perl: unsigned hilbert_box_pt(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, void * c1, void * c2) unsigned hilbert_box_vtx(unsigned nDims, unsigned nBytes, unsigned nBits , int findMin, void * c1, void * c2) <-----------------------End of Information Section----------------------------> Had problems bootstrapping Inline module 'HilbertPL_pl_301c' Can't find 'boot_HilbertPL_pl_301c' symbol in C:\HilbertPL\_Inline\lib/auto/Hilb ertPL_pl_301c/HilbertPL_pl_301c.dll at C:/Perl/site/lib/Inline.pm line 500 at HilbertPL.pl line 14 BEGIN failed--compilation aborted at HilbertPL.pl line 1076. I understand now that I probably have a typing issue, but where to start? There is a lot of c code with which I am not familiar, and I cringe at adjusting it too much for fear of breaking it, but here is what I do know: There are only 8 functions defined in hilbert.h and here are their signatures:
there are also two typedefinitions at the top of the file:
now that is just the header file. The implementation in the .c file is huge. Where would I start to find out what types PERl can't handle or vice versa since I am calling the functions from perl.? Where will this adjustment take place? In the perl script, or will I have to write a tydef file like the xstut shows on one example? Lastly, where do people talk about this stuff? I can't imagine that stuff like this is uncommon, yet it is a pain to find good help on it... Thanks Ketema | [reply] [d/l] [select] |
by tachyon (Chancellor) on Sep 29, 2004 at 00:23 UTC | |
The Inline C docs tell you what types are supported natively (for conversion). You can handle any type you like but since you can define an infinite number...... You have several issues. First you don't seem to understand typing properly (based on assigning floats to integers in the C++ example above). You also don't seem to understand what header files are for. This is pretty basic stuff and makes it hard to know where to start. So what's a header for. Well first you don't need one. All the code can be in the main.c All the code can be in the header.h for that matter. To really understand headers you need to understand types and functions and how compilers work. We declare types using typdef statements for our convenience. Rather than write unsigned long long we might use a typdef to alias that to uint64. The preprocessor effectively does a search and replace, replacing every instance of uint64 with 'unsigned long long' which is a type the compiler understands. The function declarations in the header help the compiler. Under the covers when you call a function this is what happens (simplified). The arguments to the function are pushed onto the stack. The compiler knows how much space it need because an int will take 4 bytes, a short 2 bytes, a char 1 byte, a pointer 4 bytes, etc. The memory address of the instruction following the function call is also pushed onto the stack (so we know where to return to). Last of all control of execution passed to the entry point (first instruction) of the function. The function will strip it arguments off the stack, do its stuff, push its return value onto the stack, and then return control of execution to the return location (the instruction following the function call). In order for the compiler to put together the necessary code it needs to know what arguments a function takes and what it returns. By declaring the functions as prototypes in the header file you avoid issues with code like:
In this code the compiler gets to func1, sees the call to func2 but does not know how to handle it. By declaring the functions in the header you avoid compile errors like this. The header declaration must be exactly the same as the real function. All you need to do is cut and paste the function call up to the opening curly and add a ; A header file lets you declare a function. At the compiler level that is essentially just an argument list, return type and and *entry point*. The entry point is where the actualy code that does the stuff lives. You can compile C without having this code present. For example take stdio.h You can find stdio.h but you won't find stdio.c So how does that work. The compiled binary code that actually does the stdio stuff is found in stdlibc (cc and gcc on *nix) or msvcrt (cl.exe on win32). When you compile your code you get an object file. To make it work it is linked to the C library code that actually implements the functions. Linking can be static in which case the relevant binary code from the library is actually stuck into your final executable of dynamic in which case it it not. With dynamic linking you depend on the fact that the stdlib functions will be found at runtime. These are the .lib and .dll files on Win32. Anyway Inline will give you the .al error if it can't do the type conversion automatically. The header declaration 'unsigned varname' is shorthand for 'unsigned int varname' where the 'int' declaration is implicit. Inline may of may not cope with that. If as you said you only included the main.c code then there is an obvious problem. In this code there will be lots of bitmask_t types, but without the header the compiler has no idea what that is. Handling the bitmask_t coord[] pointer and its conversion will be your main issue. There are several ways to do it, including the one I showed you before. It is not that hard. I suggest getting just one function working to start. Rinse and repeat. cheers tachyon | [reply] [d/l] |
by ketema (Scribe) on Sep 28, 2004 at 15:29 UTC | |
| [reply] |