|
Jim Langston <jlangston@conexfreight.com> wrote: > > Scott, > > I thought about doing it something like this, but how do > you know the Parm1 size before hand? Or does it matter? > > You are setting Parm1 up as 3072 bytes, how do you know > it is this size? And does it matter? You don't need to know the size beforehand... I picked 3072 because I felt it'd always be long enough to allow me to get the address of the start of my record buffer. Its possible that it won't work if I'm using a really large record format, (but you usually know at least the APPROXIMATE size of your record format at compile time) All the array is doing is proving me with a way of offsetting my pointer. IF you're using a newer version of the operating system, and can do direct pointer arithmetic, you don't need the array at all, and then you don't have to worry about sizes at all... > > I thought that if I specified a parameter larger than my actual > parameter I would get problems. For instance, say I had > 2 parameters I was passing as length 5 strings. If I declared > them as length 10 in my program, wouldn't I actually get both > passed values in my first parameter? You might -- but you can't rely on that fact. Parameters are passed by "reference". This means that for each parameter, the program making the call passes the memory address that the paramter is stored in, and the program thats being called puts its parameters into the area of memory that the calling program passed. Does that make sense? Here's a (somewhat oversimplified) example: The calling program has two strings declared, 5 bytes each. Lets call them String1 & String2. At startup, it asks OS/400 for two areas of memory, each 5-bytes long. The operating system tells the program that it can use (for example) area 1A amd area 27 So the memory might look like this (purely an example) 1 2 3 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABDEF ---already-used-memory----XXXXX--used--XXXXX--free-memory---- Where XXXXX denotes the areas of memory that were given to the program to use. Now, the program puts some data into those areas. c eval String1 = 'Data1' c eval String2 = 'Data2' Memory now looks like this: 1 2 3 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABDEF ---already-used-memory----Data1--used--Data2--free-memory---- Now it calls another program: c call 'PGM2' c parm String1 c parm String2 Because String1 is area 1A, and String2 is area 27, what its actually doing is telling the program that its to put its first parm in area 1A, and the 2nd parm in area 27. So as Pgm2 starts up, it checks its parameter definitiions, and it has this: c *entry plist c parm EntParm1 10 c parm EntParm2 5 Because these are parameters, rather than requesting an area of memory from the operating system, it takes the area that was given by the calling program. EntParm1 is in area 1A, EntParm2 is in area 27. Memory still looks like this, so: 1 2 3 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABDEF ---already-used-memory----Data1--used--Data2--free-memory---- XXXXXXXXXX XXXXX This is where the parms would be... So, because we made EntParm1 10 bytes long, it'll be pointed at the "Data1" but then will go on to look at whatever is in the area of memory beyond that... (which is unknown to us) If (by luck) the operating system had placed String1 in area 1A, and String2 in area 1F, then we would've gotten both strings in one... and this probably happens frequently, but its not something we can rely upon. If we did, we'd have "random crashes" (much like we associate with Windows programs) when the area of memory allocated didn't happen to be contiguous. > > Perhaps this is a good time to use the VARYING length > definition? If you're using a release of OS/400 new enough to use a VARYING length field, you can probably do direct pointer manipulation, as well. If this is the case, you don't need to define a field there at all, just offset the pointer "NewOffset" bytes from the beginning of the data structure. It doesn't matter that "NewOffset" takes you beyond the length of "Parm1" because when you declare parameters, you're not allocating the memory for them. The CALLING program is. In this case, the operating system declares the memory, and you can trust it to declare enough memory that the offset that its sending you won't exceed that space. Of course, if you're worried about it, the length of the data is also passed to you in the 2nd parm. You can double check it by doing something like this: c if NewOffset+%SIZE(dsRecord) > Parm2 c*** .. handle situation where not space was allocated for the c*** size of the externally defined data structure .. c endif Hope that helps... (If it doesn't, I'm not sure how to explain it) +--- | This is the RPG/400 Mailing List! | To submit a new message, send your mail to RPG400-L@midrange.com. | To subscribe to this list send email to RPG400-L-SUB@midrange.com. | To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com. | Questions should be directed to the list owner/operator: david@midrange.com +---
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.