× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Thanks Scott.

I think we saw the asterisk in the "char(*)" and our rusty brains
interpreted it as "Pointer" instead of "variable size"...

It's Monday.

Thanks for the tips, too.  I've often tried to put BIFs in the parms on
my program calls just because it seems intuitive, and when I go to
compile I get the "parameter not valid as a parameter passed by
reference" error. Now I know a better way around that.  

Greg

P.S. For some reason, your reply to me got tagged with a reply address
of rpg400-l@xxxxxxxxxxxxxxxx instead of the usual
rpg400-l-bounces@xxxxxxxxxxxxx  I sent this reply once already and
realized when it didn't show up on the list that it went to the
aforementioned bogus address.  Weird. 

|-----Original Message-----
|From: Scott Klement [mailto:rpg400-l@xxxxxxxxxxxxxxxx]
|Sent: Monday, June 19, 2006 12:50 PM
|To: Fleming, Greg (ED)
|Subject: Re: QSYGETPH API
|
|> I've posted our code below.  Does anyone see anything obvious we
might
|> be doing wrong ?
|
|Yes, very obvious.  You're passing a pointer instead of a character
field
|for
|the password!!
|
|Here's your prototype:
|
|>     D GetProfile      Pr                    ExtPgm('QSYGETPH')
|>     D  UserID                       10A
|>     D  Password                       *
|>     D  Handle                       12A
|>     D  ErrorCode                   256A   Options(*Varsize : *NoPass)
|>     D  PswLength                    10I 0 Options(*NoPass)
|>     D  CCSIDCode                    10I 0 Options(*NoPass)
|
|The API documentation states that the 2nd parameter is a CHAR field,
not a
|pointer.  Instead of passing a string containing the password, you're
|passing a
|memory address to the API.  The API is reading that memory address, and
|thinking that you're intending that 16-byte hex value (the address) to
be
|the
|password.
|
|For example, when the subprocedure starts, the program needs memory for
the
|"password" variable (it gets it's own memory, since it's passed by
value.)
|The
|program asks the operating system for 10 bytes of the memory, and the
os
|says
|(for example) that it can use 10 bytes starting with memory address
|x'8000000000000000C655098D43073340'.
|
|It then copies this address to the passwordin variable -- and passes
that
|number, x'8000000000000000C655098D43073340', instead of the actual
|password, to
|the API.  The API thinks that this number is supposed to be the
password --
|and
|tries it, only to find that it's not the right password for the userid.
|
|Change your prototype to look like this:
|
|>     D GetProfile      Pr                    ExtPgm('QSYGETPH')
|>     D  UserID                       10A   const
|>     D  Password                  32767A   const options(*varsize)
|>     D  Handle                       12A
|>     D  ErrorCode                   256A   Options(*Varsize : *NoPass)
|>     D  PswLength                    10I 0 const Options(*NoPass)
|>     D  CCSIDCode                    10I 0 const Options(*NoPass)
|
|Note that in addition to coding the password as a character field, I
also
|made
|the input-only fields be "const".  This'll make the API easier to call
in
|many
|situations, it's also more self-documenting.
|
|When you call it, do this:
|
|         //?Retrieve user Profile;
|
|              CallP  GetProfile( %late(LC:UC:UserID)
|                               : password
|                               : handle
|                               : ERRDS:
|                               : %len(password)
|                               : 0 );
|
|Note that because I used CONST on the prototype, I can do some
calculations
|on
|the call to the API. This makes the code shorter, eliminates the need
for
|temporary one-use variables, and IMHO it's easier to read, because I
|mentally
|look at the call and say "Call with uppercase userid, call with the
length
|of
|the password field", etc.  If you put variables there, I have to go
back
|and
|examine them to see what you did to them.
|
|I also changed your CCSID from 37 to 0.  37 means that it'll always be
|EBCDIC
|for English languages in the USA.  If this code is ever run elsewhere,
the
|fact
|that this is hard-coded might screw someone up. Changing it to 0 tells
it
|to
|retrieve the job's CCSID value and use that. That's usually a better
choice
|for
|the default.
|
|But, all of these are just "tips" for improvement.  The actual error is
the
|fact that you're passing a pointer instead of a character field for the
|password.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.