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:
__declspec(dllimport) bool myTableCompare(myTable lhs, myTable rhs, my
+Table* output, unsigned int *count, double relative_tolerance, double
+ absolute_tolerance)
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:
my $TableComparer = new Win32::API("myDll.dll","myTableCompare", 'NNPP
+DD','I','_cdecl');
I'm not completely sure, because I get a segmentation fault when I call $TableComparer with the following parameters:
$count = 1;
$pointerToCount=pack('I',$count);
$RelativeTol=0.001;
$AbsTol=1.0;
my $areTheSame=$TableComparer->Call($LeftTable,$RightTable,$packedOutp
+utTable,$pointerToCount, $RelativeTol,$AbsTol);
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.
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... |