|
>>I'd really like to understand the rationale behind writing the code that >>way to begin with. Was it just random trial and error until something >>worked? Why would you ever do that? What was the thought process behind >>it? You're of course correct in your statement that some of this code has been stumbled upon - experimenting with options until it worked, often not understanding the underlying details. I'm the first person at this location to even think in terms of modules, user spaces, prototypes, etc. - so unfortunately I've had little precedent to follow (and as we all know, programming is partially a plagiaristic art). But that's why when I do reach a point of things not adding up, I ask for feedback - and I'm always looking for a better way. It's not important that my way is better necessarily... >>You could also use QUSCRTUS and QUSPTRUS to create and get a pointer to a >>user space instead of allocating RAM with the %alloc() BIF. It'd require >>more code, but you'd end up with the same results (more or less). Since I already have the modules written to create a user space and return the pointer to it, it's not a lot of work. I understand how you use alloc to get more space assigned to the variable than the d-spec definition would normally allow. Since I prefer the user space method, how would I set that up? Let's say my user space pointer is USP_Ptr. I'll need to define a variable based on that. So, D MyVar ??????A Based(USP_Ptr). How big do I make the variable. I kept thinking that if I make it the largest I could define on the D-spec (32767) that's all the API would return for me. Or - is the 'length of receiver variable' (staying with the QMHRDQM API example) the key? Will the API use however much space I tell it to in that variable, regardless of the definition of MyVar. Example. D MyVar 1A Based(USP_Ptr). D MyVarLen 10I 0 Inz(1048544) *-or whatever size I want-* Then when the API is called, it will start putting data into MyVar but continue as far as the MyVarLen lets it go? If this is the case, I can run with that. I think that's a little obscure myself, but I'll agree that it's a little more clear than my weird pointer structure I'd forced to work before. (The reason I went with odd pointer definitions is that I couldn't resolve in my mind how long to make MyVar). Thanks for the help. Always looking for a better way. JPW The bitterness of poor quality remains long after low pricing is forgotten! Cautillo, Leon M. -----Original Message----- From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement Sent: Tuesday, 28 February 2006 20:08 To: RPG programming on the AS400 / iSeries Subject: Re: QWCCVTDT Weirdness, solved! > I am still interested on any thoughts about how the pointer based on a > pointer thing works (because it does), and if there is a better way. Oh, now that I've looked it over again and read Tom's reply, I can tell you exactly how it works. Basically what you were doing is equivalent to doing this: D ds D InVar 1 16* D DTSField 1 17A I don't know what the name of the field containing the DTS timestamp was (since you didn't post it) so I made one up. But hopefully you understand what I'm saying. They occupied the same spot in memory. Granted, you used pointer logic rather than a data structure, but it had the exact same effect. It didn't matter which one you passed to the API, since they contained the same value. As long as you made sure DTSField was set to a valid DTS timestamp (and therefore made InVar an illegal pointer value) the code would work. It makes no sense to do that -- but that's what you did. > For example, if you wanted to dump all the messages in a data queue into > a user space with the QMHRDQM API, and the API expects a character > argument for the output variable, how would you do it? Well, the method you're using wouldn't help with that. But you could do it this way if you wanted to: D mySpace s * D InVarPtr s * D InVar s 1024A based(InVarPtr) D x s 10I 0 ** Ask the OS for 1mb of memory: C eval mySpace = %alloc(1024 * %Size(InVar)) ** set the entire space to blanks: c for x = 0 to 1023 c eval InVarPtr = mySpace + (x * %size(InVar)) C eval InVar = *blanks c endfor . . ** when you're done, let the OS have it's memory back C dealloc mySpace Basically, InVar views 1k of memory at a time. So in the above example, I've reserved 1 mb of memory to the MySpace pointer. And then I've changed InVarPtr to tell it to view different sections of that 1mb of memory. (In this example, I used that functionality to blank it out.) To pass the contents of the 1mb space to the API you'd do this: ** Ask the OS for 1mb of memory: C eval InVarPtr = mySpace C CALL 'SOMEAPI' C PARM inVar Since the current address of InVar is the same as the address stored in mySpace, it'd be the memory that's allocated to mySpace that'd be used by the API. > I needed a lot more than 32767 characters for a large data queue. In this case, I've used the %alloc() BIF, which is capable of allocating up to (approx) 16mb. That's a lot more than 32k! You could also use QUSCRTUS and QUSPTRUS to create and get a pointer to a user space instead of allocating RAM with the %alloc() BIF. It'd require more code, but you'd end up with the same results (more or less). I don't know if the data queue APIs support it, but if 16mb wasn't enough, you COULD allocate the memory in teraspace. If you did that, you'd be able to allocate as much as 1 terabyte to MySpace. So... that should be enough, eh? > By basing a pointer variable on a pointer that is the address to the > user space, and then passing that based pointer to the QMHRDQM API it > works nicely, but I've sometimes wondered if there is a better way. It makes no sense to base a pointer on a pointer for what you're trying to do. Base a character field or data struture, or whatever you need to work with on the pointer. Not another pointer! Anyway, I'm glad you figured it out.
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.