I am nitpicking your code.
$CreateTable = new Win32::API("myDll.dll","myTableCreate", 'V','N');
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
{ 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]); } }
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.

You do things like
if($isLoadedRight>0){print("Loading table error on ".$pathTabl +eRight.": ".@DllTblStatus[$isLoadedRight]."\n");}
and
$pass = $pass && ($LeftTable>0 && $RightTable>0 && $outputTable>0) +;
but here you did
$pass = $pass && ($isLoadedLeft==0 && $isLoadedRight==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).
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
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).
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?

In terms of special magic return values and pointers, MS DLL that return "HANDLE", either return -1 or 0 on failure (read the docs, some do -1, some do 0, some do both), or a HANDLE. With an unknown function, everything under 2^16 (65536) or 2^12 (4096, 1 page) is not a pointer. In GDI handles, the upper 16 bits is a generation counter to prevent a new handle from being the same as a recently freeded handle, so things that use a freeded handle will fail rather than work erratically on the new handle. The lower 16 bits is the index into an array, see http://msdn.microsoft.com/en-us/library/ms810501.aspx. Kernel handles are different.

It should be obvious that myTableCompare is giving you a table */void * to do something with. Since if its "the same" it gives you 1, I will guess 0 is error, and "different but success", you get a table with the delta table. So myTableCompare really returns a myTable, with opaque being 0, 1, or a table. Also I've never seen you free any of the table *s. You will have to do that eventually.

Do you have docs or source code for this DLL or only the header file? Download StudPE and look at the export (and if you have time or curiosity, import table) table of that DLL. The PE Export table will show everything you can possibly call in that DLL from C, unless that is a C++ DLL. If its C++ then you have a big problem (virtual tables, etc). The PE export table does not show the prototypes of the functions though. There are ways to reverse engineer and learn the prototypes of the functions if you have the time. I've done it successfully before, since I have some assembly skills.

In reply to Re^13: WIN32::API and void* by bulk88
in thread WIN32::API and void* by sgv_81

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.