FFSparky has asked for the wisdom of the Perl Monks concerning the following question:

I'm having a problem calling a function so to prove that I have the module figured out (granted I'm a novice PERL gent) I put two functions in the following code. The first one works, the second function call works but the return code is not what I am expecting "0" and I could get a -1 or -2. What I am getting for a return code is 1949630464 which really baffles me.... Thanks for the suggestion BrowserUK, I cleaned up the code, unfortunatly still no luck.
use Win32::API; use strict; use warnings "all"; # MessageBox API - Reference: http://msdn2.microsoft.com/en-us/libra +ry/ms712455.aspx # int MessageBox( # HWND hWnd, # LPCTSTR lpText, # LPCTSTR lpCaption, # UINT uType # ); my $hwndOwner = 0; my $LpszText = "Message Box Text"; my $LpszTitle = "Message Box Title"; my $uStyle = 0; #define MB_OKCANCEL 0x00000001L my $fnMessageBox = new Win32::API("user32", "MessageBox", 'NPPN', 'I') +; my $call1ret = $fnMessageBox->Call($hwndOwner, $LpszText, $LpszTitle, +$uStyle); print "MessageBox Return Code: ".$call1ret."\n"; # SQLAllocHandle API - Reference: http://msdn2.microsoft.com/en-us/l +ibrary/ms712455.aspx # SQLRETURN SQLAllocHandle( # SQLSMALLINT HandleType, # SQLHANDLE InputHandle, # SQLHANDLE * OutputHandlePtr); my $HandleType = 1; my $InputHandle = 0; my $OutputHandlePtr = ''; my $fnSQLAllocHandle = new Win32::API("odbc32", "SQLAllocHandle", 'PPP +', 'I'); my $call2ret = $fnSQLAllocHandle->Call($HandleType, $InputHandle, $Out +putHandlePtr); print "?? ".$^E."\n\n"; print "SQLAllocHandle Return Code: ".$call2ret."\n";

Replies are listed 'Best First'.
Re: Win32::API Help
by BrowserUk (Patriarch) on Sep 27, 2007 at 23:24 UTC

    If you used strict and warning, and fixed your code to avoid the first bunch of errors, then you'll get this set of errors:

    c:\test>junk syntax error at c:\test\junk.pl line 34, near "$OutputHandlePtr;" Bareword "null" not allowed while "strict subs" in use at c:\test\junk +.pl line 13. Bareword "N" not allowed while "strict subs" in use at c:\test\junk.pl + line 18. Bareword "P" not allowed while "strict subs" in use at c:\test\junk.pl + line 18. Bareword "P" not allowed while "strict subs" in use at c:\test\junk.pl + line 18. Bareword "N" not allowed while "strict subs" in use at c:\test\junk.pl + line 18. Bareword "I" not allowed while "strict subs" in use at c:\test\junk.pl + line 18. Bareword "null" not allowed while "strict subs" in use at c:\test\junk +.pl line 32. Bareword "N" not allowed while "strict subs" in use at c:\test\junk.pl + line 33. Bareword "N" not allowed while "strict subs" in use at c:\test\junk.pl + line 33. Bareword "P" not allowed while "strict subs" in use at c:\test\junk.pl + line 33. Bareword "N" not allowed while "strict subs" in use at c:\test\junk.pl + line 33. Execution of c:\test\junk.pl aborted due to compilation errors.

    And if you pay particular attention to the two 'Bareword "null"' messages, then you might get somewhere.

    Also, it is often, but not always useful, to print $^E in a string context if the api call fails.

    Update: If you are using AS perl, then take a look at the html pod for the package Win32, wher eyou will find that MessageBox() is available without using Win32::API.

    Win32::MsgBox(MESSAGE [, FLAGS [, TITLE]])

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Win32::API Help
by almut (Canon) on Sep 27, 2007 at 21:27 UTC

    Just guessing... but have you tried specifying "I" (int) instead of "N" (long) as the return value type (4th parameter)?  (The API docs don't explicitly say what type/size SQLRETURN is (at least it's not immediately evident to me), so I'd just try likely candidates...)

Re: Win32::API Help
by syphilis (Archbishop) on Sep 27, 2007 at 23:58 UTC
    What I am getting for a return code is 1949630464

    sql.h defines the 4 possible return values (SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, and SQL_ERROR) to 0, 1, -2, and -1 (respectively).

    Cheers,
    Rob
Re: Win32::API Help
by Anonymous Monk on Sep 28, 2007 at 00:22 UTC
Re: Win32::API Help
by FFSparky (Acolyte) on Sep 28, 2007 at 02:22 UTC
    Thanks for the suggestion BrowserUK, I cleaned up the code and need to use strict more often, unfortunately still no luck in figuring this out. My guess is it's something with the parms as I wrote a quick C (and I'm a novice C person as well, but COBOL on the other hand ;^)... ) program to make sure I was passing the correct values for the parms in perl. And to answer Anonymous Monk, the example I am playing with is more for me in gaining knowledge in working with windows API's and I just happened to pick this particular function.
      the example I am playing with is more for me in gaining knowledge in working with windows API's

      You're probably better off getting hold of a compiler (say, the freely available MinGW port of gcc) and using it and Inline::C to access the Windows API's. It's fairly trivial with Inline::C. The following script outputs 0:
      use warnings; use strict; use Inline C => <<'EOC'; #include <sql.h> int foo() { SQLHENV henv = SQL_NULL_HENV; return SQLAllocHandle(1, 0, &henv); } EOC print foo();
      Admittedly that doesn't do anything useful, but at least it returns a sane value and is nowhere near as obtuse as Win32::API.

      I must confess that I've spent quite some time trying to get the Win32::API version to return a sane value ... and have failed miserably. Usually, when I can get the Inline::C rendition working, I can then get the Win32::API rendition to work correctly ... sadly, not tonight :-)
      I assume it's because I haven't found the correct way to deal with the 3rd argument, but I really don't know.
      Update: Nope ... looks like apl and Corion have picked up the scent, however.
      Update 2:Yep ... I just checked and the SQLRETURN type is a short ... and apparently Win32::API simply fills the other 2 bytes with garbage.

      Cheers,
      Rob
        Thank you all for sharing your wisdom, I have gained knowledge :^)

        I believe syphilis is correct in Win32::API does not deal well with short data types. So I took the suggestion and played around with InLine and now have another option for calling APIs:
        use warnings; use strict; print "InLineC.pl Started:\n\n Now to Execute some C code:\n\n"; print " fnTest Returned: ".fnTest()."\n"; print "\n Back from the C Code\n\nInLineC.pl Finished.\n"; use Inline C => <<'END_C'; #include <sql.h> int fnTest() { SQLHENV env; SQLRETURN ret; ret = SQLAllocHandle(1, 0, &env); return ret; } END_C
Re: Win32::API Help
by apl (Monsignor) on Sep 28, 2007 at 09:54 UTC
    Your return value (1949630464 decimal) is 74350000 hex. Are you certain you don't need to only look at the low 16 bits? If so, you got a successful return.

    I'm just tossing out an idea; I'm not familiar with the module you're using.

      Exactly. Googling for SQLAllocHandle 1949630464 has as one of the few hits this page, where somebody tackled the same problem with Common Lisp (it seems). If one encounters a magic number, it's always good to Google for that.