in reply to Re^12: WIN32::API and void*
in thread WIN32::API and void*
Put the cdecl thing on. Cdecl should be on for every C function, no exceptions. So far we learned that there are no stdcall functions in your DLL. I explained earlier why myTableCreate wont crash as stdcall even though stdcall is wrong. In your debug code's print messages you call the tables "handles". I dont know if that is correct. Win32 API calls it a HANDLE because "void *" doesnt work with Win32 API. Here is a tool to prove if they are pointers or not$CreateTable = new Win32::API("myDll.dll","myTableCreate", 'V','N');
This is a wrapper around IsBadReadPtr. IsBadReadPtr will literally tell you if you will access violation/seg fault on any particular pointer from attempting to read that pointer block. All your 48,000,000s tables are probably pointers. What the length of the table memory block in the 48,000,000s? I dont know, maybe you know since you have the docs to your DLL. I can tell you that it is atleast 4 byte long since that is the minimum allocation size, cuz you have a 4 or 8 byte header behind the start of the malloc block that the malloc system puts there for book keeping, to make the pools tidy, the actual allocation is 8 (4 byte header, 4 bytes to you, you asked for 1-4 bytes) or 16 (8 byte header, 8 bytes to you, you asked for 1-8 bytes). Now if you use IsBadReadPtr, either all the table handles are readable, or none of them are readable. 48,000,000 things can really be a GUID/HANDLE/Encrypted pointer/record number/generation counter and not a memory block. Also the 48,000,000 may not 1 for 1 line up with malloc calls. For example, the 48,000,000 pointers might be pointers into 1 malloced block that is an array of all table headers that are live by the DLL, inside the DLL, so you couldn't call free() on then even if you wanted. Remember IsBadReadPtr can not tell the difference between allocated from the OS but free memory, and allocated from the OS and allocated from malloc memory. IsBadReadPtr is just a debugging tool, you dont have to use it.{ my $IsBadReadPtr = Win32::API->new( 'kernel32.dll', 'BOOL IsBadReadPtr( UINT_PTR lp, UINT_PTR ucb) +', ); die "getting IsBadReadPtr failed" if !$IsBadReadPtr; sub IsBadReadPtr { return $IsBadReadPtr->Call($_[0], $_[1]); } }
andif($isLoadedRight>0){print("Loading table error on ".$pathTabl +eRight.": ".@DllTblStatus[$isLoadedRight]."\n");}
but here you did$pass = $pass && ($LeftTable>0 && $RightTable>0 && $outputTable>0) +;
Why not do != 0 instead of > 0, what if its a negative number? (in 0.68 all return/out values are signed, unsigned is ignored and you get signed, thats a bug with 0.68).$pass = $pass && ($isLoadedLeft==0 && $isLoadedRight==0);
Yep, the reason for void ** is because the DLL will swap out the table pointer if it internally reallocates the table pointer because the old table pointer didn't meet the DLL's requirements (size, location, etc). It also means you need to be diligent, to not use the old void * (which will crash since its freed/reallocated to something else memory).These are the empty tables HANDLEs: Left Table: 48120353 Right Table: 48120401 Output Table: 48120449 ... Table communication between perl and dll is correct. Pass code: 1 ... These are the empty tables LPHANDLEs (Pack Option: L): Left Table: $VAR1 = "!B\336\2"; Right Table: $VAR1 = "QB\336\2"; Output Table: $VAR1 = "\201B\336\2"; ... Tables: C:/Temp/Requests/TableTest1.TBL and C:/Temp/Requests/TableTest +1.TBL loaded correctly. Pass code: 1 ... After loading the tables with the files, the tables LPHANDLEs (Pack Op +tion: L): Left Table: $VAR1 = "\31\261\337\2"; Right Table: $VAR1 = "y\333\340\2"; Output Table: $VAR1 = "\201B\336\2"; ... After laoding the tables with the files, the tables HANDLEs (Unpack Op +tion: L): Left Table: 48214297 Right Table: 48290681 Output Table: 48120449
In this case, The returned value of myTableCompare was: 48168704. Is this expected? Is the boolean defined as 1 if it's True and not 1 (in this case 48168704) if it is False. I would personally have expected a 0 instead.No. Error numbers in unix http://www.ibm.com/developerworks/aix/library/au-errnovariable/ and in Windows, 0 is success http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382%28v=vs.85%29.aspx. BOOL in windows is 0 failed, true. MS headers say 1 is TRUE, and BOOL functions usually return 1, I've never seen a BOOL that returns something other than 1 on success, but everyone tests for true, not == 1, note you have a "bool" not a microsoft "BOOL", and your header file and the prototype is very messed up if it says bool/BOOL and delivers pointers. If the programmer was responsible, there should be symbolic constants somewhere in your header file that say what the non pointer return values/return flags are, and what is the cut off number between table pointers and status codes for myTableCompare. Who wrote this DLL?
|
|---|