|
Hi Jim,You state that the following code works. I find that very hard to believe, since the code doesn't make sense. (I tried it, it doesn't work on my system)
InVarPtr S * (the pointer to the variable that contains the *DTS data to convert, passed into program) InVar S * Based(InVarPtr) OutVar S 17A InFmt S 10A Inz('*DTS') OutFmt S 10A Inz('*YYMD') Call 'QWCCVTDT' Parm InFmt Parm InVar Parm OutFmt Parm OutVar
Why doesn't this code work?a) The QWCCVTDT API requires at least 5 parameters, and you're only passing 4.
b) The API is expecting "InVar" to be a character string, and you're passing a pointer. Therefore, when it reads it, it'll get the bytes of a memory address rather than the bytes of an actual DTS date.
Of course, with (b) it may look like it's working, but what's really happening is that the API is interpreting a memory address as a DTS timestamp -- which of course it isn't.
Keep in mind that APIs are just programs that someone wrote. If you write a program that (for example) accepts a date field (type D) as a parameter, and someone decides to call it and pass it a packed (type P) field, it won't work, right? The same is true for an API. If it expects a character field, you have to pass a character field. You can't decide to pass a packed field, or pointer field, or date field or anything else. Only a character field will work.
You may be confused because sometimes people will pass a character field by reference instead of a pointer field by value. However, that's not what you're doing... you're passing the pointer by reference instead.
Every variable is stored in a computer's memory somewhere. So, logically, there's a memory address associated with each variable. When parameters are passed from one place to another, it's done by "sharing" that memory between the caller and the program that it calls. Basically what it does is pass the memory address so that the called program knows where to look in memory for the parameter. Since both programs have put their variables in the same spot in memory, changes made to one affect the other. (Just like overlaying fields in a data structure.) This is called "passing by reference"
A pointer is a variable designed to hold a memory address. Thus, if you pass a pointer by VALUE (and it MUST be by value!) what you do is pass the address stored in that pointer. Since it's still an address being passed, and you can make sure that address points to a character field, it can have the same effect as passing the character field by reference.
However: a) You can only pass things by VALUE to a subprocedure, not a program.b) In your case, you weren't passing by VALUE, so instead of passing the address stored in the pointer, you're sharing the memory of the pointer itself.
In your case, when the API reads the parameter, it'll read a memory address and try to treat it as a DTS timestamp!
InVar S 17A OutVar S 17A InFmt S 10A Inz('*DTS') OutFmt S 10A Inz('*YYMD') Call 'QWCCVTDT' Parm InFmt Parm InVar Parm OutFmt Parm OutVar
This is much better. You still have the problem that you're only passing 4 parameters, and the API requires at least 5. Other than that, this code is correct. And I tried it (with the 5th parm added) and it worked just fine.
...but you say that this one doesn't work... and that confuses me.Here's the exact code that I'm using. This is a complete program -- you should be able to load it without any changes, and compile and run it and it should output "DSPLY 20050516132424437" (you may have to display the job log to see the text, though)
D InVar s 17A inz(x'89A37F16E9B68000') D OutVar s 17A D InFmt s 10A inz('*DTS') D OutFmt s 10A inz('*YYMD') D ErrorCode ds D BytesProv 10I 0 inz(0) D BytesAvail 10I 0 inz(0) C CALL 'QWCCVTDT' C parm InFmt C parm InVar C parm OutFmt C parm OutVar C parm ErrorCode c OutVar dsply c eval *inlr = *onBetter yet, re-code the program to use a prototype. The prototype will protect you against passing the wrong parameters to the API (that is assuming, of course, that the prototype is written properly). That way, you won't make the same mistake in the future.
Good luck
As an Amazon Associate we earn from qualifying purchases.
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.