in reply to Re^7: WIN32::API and void*
in thread WIN32::API and void*
Mission accomplished. It was the "_cdecl". I've included it and tables are loaded perfectly!!!.
I have some doubts about how HANDLE parameters will translate into the non-prototype calls. I've made a test with myTableCreate() and I think I should treat them as 'N' (I print the dumper for both the prototype and the non-prototype and I get $VAR1=48120369 and $VAR1=48120417, which doesn't seem bad). Furthermore, I'm not sure how they'd be packed (if they'd need to) before passing them to an API function as parameters. For instance:
Assuming BOOL=INT, which seems to work fine with the Kernel32 API BOOL Beep(long,long), the above C declaration translate into the following perl call:__declspec(dllimport) bool myTableCompare(myTable lhs, myTable rhs, my +Table* output, unsigned int *count, double relative_tolerance, double + absolute_tolerance)
I'm not completely sure, because I get a segmentation fault when I call $TableComparer with the following parameters:my $TableComparer = new Win32::API("myDll.dll","myTableCompare", 'NNPP +DD','I','_cdecl');
Note that in this version of the code, I've passed $LeftTable and $RightTable without packing them before. I've tried to pass their J-packed versions but I still get a segmentation fault.$count = 1; $pointerToCount=pack('I',$count); $RelativeTol=0.001; $AbsTol=1.0; my $areTheSame=$TableComparer->Call($LeftTable,$RightTable,$packedOutp +utTable,$pointerToCount, $RelativeTol,$AbsTol);
Another doubt I have comes from the unsigned int pointer in the previous example, I have assumed that the signature is 'NNPPDD', and I've created the pointer using pack('I',$count), which I don't know whether it's right.
By the way this is the part of the code that works, in case somebody needs it:
#! /usr/bin/perl use Win32::API; # Load the table creator from the dll. # C signature: __declspec(dllimport) myTable myTableCreate(); # typedef # struct myTable { # void* opaque; ///< Opaque pointer to storage # } myTable; $pass=1; my $CreateTable = new Win32::API("myDll.dll","HANDLE myTableCreate()") +; if(not defined $CreateTable) { die "Can't import API myTableCreate(): $!\n"; } #Create empty tables. $pass = 1; if($pass) { my $LeftTable = $CreateTable->Call(); my $RightTable = $CreateTable->Call(); my $outputTable = $CreateTable->Call(); # Make sure that the function does return a memory position, and n +ot a 0. $pass = $pass && ($LeftTable>0 && $RightTable>0); if($pass){print("Empty Tables Succesfully Created. Pass code: ".$p +ass.".\n");}; } # pack the table. if($pass) { my $packedLeftTable = pack('J',$LeftTable); my $packedRightTable = pack('J',$RightTable); my $packedOutputTable = pack('J',$outputTable); $pass = $pass && (unpack('J',$packedLeftTable) == $LeftTable && un +pack('J',$packedRightTable) == $RightTable && unpack('J',$packedOutpu +tTable) == $outputTable); if($pass){ print("Pack-Unpack round trip completed. Pass code: ".$ +pass."\n");} } # Path definition. my $pathTableLeft = 'C:/Temp/Requests/testTable1.TBL'; my $pathTableRight = 'C:/Temp/Requests/testTable2.TBL'; # Load the function. # Load the table file loader from the dll. # Some info about the API function: # __declspec(dllimport) enum cStatus myTableLoadFromFile(char const* f +ilename, myTable* raw_result); # enum cStatus will treated as an int and interpreted using the array +@DllTableStatus. my $LoadTableFromFile = new Win32::API("myDll.dll","myTableLoadFromFil +e", 'PP', 'I','_cdecl'); if(not defined $LoadTableFromFile) { die "Can't import API myTableLoadFromFile(): $!\n"; } if($pass) { my @DllTblStatus = ("OK Status, no errors", "Failed to allocate me +mory", "Unable to open or save file", "Unable to convert value to req +uested type", "Unknown error", "Validation Failed", "Cell could not b +e found"); my $isLoadedLeft = $LoadTableFromFile->Call($pathTableLeft,$packed +LeftTable); my $isLoadedRight = $LoadTableFromFile->Call($pathTableRight, $pac +kedRightTable); $pass = $pass && ($isLoadedLeft==0 && $isLoadedRight==0); if($pass) {print("Tables: ".$pathTableLeft." and ".$pathTableRight." loa +ded correctly. Pass code: ".$pass."\n");} else { if($isLoadedLeft>0){print("Loading table error on ".$pathTable +Left.": ".@DllTblStatus[$isLoadedLeft]."\n");} if($isLoadedRight>0){print("Loading table error on ".$pathTabl +eRight.": ".@DllTblStatus[$isLoadedRight]."\n");} } }
PS: I'm using Windows and Cygwin, probably that's why sometimes things look a little bit MS-like and others a little bit Unix-like...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^9: WIN32::API and void*
by bulk88 (Priest) on Jul 26, 2012 at 16:55 UTC | |
by sgv_81 (Novice) on Jul 26, 2012 at 17:34 UTC | |
by bulk88 (Priest) on Jul 26, 2012 at 19:06 UTC | |
by sgv_81 (Novice) on Jul 27, 2012 at 11:20 UTC | |
by bulk88 (Priest) on Jul 27, 2012 at 15:24 UTC |