Mission accomplished. It was the "_cdecl". I've included it and tables are loaded perfectly!!!.
Good to know it wasnt a Win32::API bug or a bug in your DLL. I am
very confused, since your pack 'J' (Perl Internal Scalar Unsigned
Value) letter is 64 bits long, yet you have a x86-32 DLL and a
x86-32 Perl. Do you have one of the freak Perl builds with native 64
bit integers, but 32 bit pointers running 32 bit assembly code? I will
assume that for the rest of this post.
Win32::API's letter codes are "inspired by" but ARE NOT the same letters as for pack. 'N' for Win32::API means pointer sized number. For pack, well I thought you should be using J, since that is normally 4 bytes on 32 bit and 8 bytes on 64 bits, but for your machine, J isn't the right letter. For myTable struct, it "worked" but J was sorta a bug/bad choice. The last 4 "\x00" are ignored by your DLL, and the myTable "struct" you gave is actually 2 pointers long (8 bytes), but the DLL doesn't know and doesn't care (a property of little endian numbers). You shouldn't use J with pack for pointers in multimember structs non-stock Perl build. You need to find the appropriate letter, see pack.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.
Do not pack $LeftTable and $RightTable. They should be 12345, not
"\x12\x34....". myTable is a void * and is a HANDLE/pointer sized
integer, myTable * is a void **. I saw you create $packedOutputTable from ,$outputTable with CreateTable but never checked $outputTable for null/0/false. $pointerToCount looks fine. I don't think the 2 doubles cause problems at this point.
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.
Correct. Any 'P' letters must be "ab\x01\x02cd" strings. Never ever
123.
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...
90% of my knowledge is Visual C or ActivePerl, 10% Mingw or
Strawberry. 0% cygwin. I dont have a cygwin perl installed. Seg fault
sounds correct for Cygwin Perl, since Cygwin Perl thinks and acts like
Linux.
Can you do a print Dumper on all the parameters in "my $areTheSame=$TableComparer->Call($LeftTable,$RightTable,$packedOutputTable,$pointerToCount, $RelativeTol,$AbsTol);" before you do the Call() that crashes?
In reply to Re^9: WIN32::API and void*
by bulk88
in thread WIN32::API and void*
by sgv_81
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |