|
Thanks - this is exactly what I was looking for. And no - I don't expect to be able to see the exact pointer value and know that there was an error in a calculation (for example) because the value of the pointer would not be what I expected... In the case that started me wanting to do this, I'm testing a procedure to create a User Space and return the pointer to the header. For my test program, I'd like to display the pointer. By seeing a valid format pointer, I can trust that both the QUSCRTUS and QUSPTRUS api's worked. If I get *NULL, they didn't. The exact pointer value itself is not a guarantee that everything is OK, but one in the correct format (and knowing that the underlying code is not doing any pointer arithmetic) gives me a quick check to know that things are ok on the surface. To me it's a simple way to display that the routines worked and passed the data to each other correctly. Thanks for the suggestion on displaying the pointer. 'Cheers JPW -----Original Message----- From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement Sent: Wednesday, 2 November 2005 13:32 To: RPG programming on the AS400 / iSeries Subject: RE: Displaying/Printing a pointer value > Part of my standards is that every procedure has a test program that > will display all values returned by the > procedure. Seems to me that it'd be more useful to display the data that the pointer points to. I have yet to meet the programmer who can take a value like SPP:D572811D4306B980 and say "hey! that's not right! That API is supposed to return SPP:D572811A4306B980!" But, having said that, it's certainly possible to display the value of a pointer. > There are other ways to determine if the procedures worked. I just like > the idea of displaying the pointer value, and was looking for an easy > way. After all, it's just a number. There should be a way to convert it > to a display value. A pointer _isn't_ just a number on the iSeries. You may be thinking of a PC or Unix environment where a pointer is an integer. On the iSeries, a pointer is significantly more complex, it contains several different pieces of information that enable it to access any memory anywhere in either teraspace or single-level store. There are many types of pointers, system pointers, space pointers, procedure pointers, invocation pointers, suspend pointers, data pointers, label pointers... the format of the data in the pointer itself will be different depending on the type of pointer. But, anyway, yeah you can display a pointer. Two ways that come to mind: a) You could use the cvthc() API to read the contents of the pointer (just by specifying where the pointer is stored in memory) and it'll output a raw hex representation of the bytes that make up the pointer. For example: D cvthc PR ExtProc('cvthc') D target 32A D src_bits * value D tgt_length 10I 0 value D myPointer s * D rawHexData s 32A /free cvthc(rawHexData: %addr(myPointer): %size(rawHexData)); b) The printf() family of functions in ILE C has the ability to make a nicely formatted dump of the various pieces of info in a pointer. It's relatively easy for an RPG program to call the snprintf() API from ILE C to format the pointer: D snprintf PR 10I 0 extproc('snprintf') d buf 32767A options(*varsize) D bufsize 10U 0 value D fmt * value options(*string) D ptr * value options(*nopass) D temp s 81A D humanData s 80A /free snprintf(temp: %size(temp): '%p': myPointer); humanData = %str(%addr(temp)); Since snprintf() writes out a C-style string (i.e. null-terminated string), I write it to a temporary field, and then I use the %str() BIF to extract it into an RPG-style character field. Either of these could be used for your purposes if you really want to print the contents of a pointer. Here's a sample program (in fact, it's where the code snippets above came from) that demonstrates printing a standard space pointer, a procedure pointer, and a teraspace pointer. Each pointer is printed using both methods: H DFTACTGRP(*NO) BNDDIR('QC2LE') FQSYSPRT O F 132 PRINTER D TS_malloc PR * ExtProc('_C_TS_malloc') D size 10U 0 value D TS_free PR ExtProc('_C_TS_free') D ptr * value D snprintf PR 10I 0 extproc('snprintf') d buf 32767A options(*varsize) D bufsize 10U 0 value D fmt * value options(*string) D ptr * value options(*nopass) D snprintf2 PR 10I 0 extproc('snprintf') d buf 32767A options(*varsize) D bufsize 10U 0 value D fmt * value options(*string) D ptr * value procptr options(*nopass) D cvthc PR ExtProc('cvthc') D target 32A D src_bits * value D tgt_length 10I 0 value D myPointer s * D procPtr s * procptr D rawHexData s 32A D temp s 81A D humanData s 80A /free // Use cvthc() to create a hex dump of the contents // of a pointer. // // Use sprintf() to format a pointer's contents to make // it easier for a person to read. myPointer = %alloc(1234); cvthc(rawHexData: %addr(myPointer): %size(rawHexData)); snprintf(temp: %size(temp): '%p': myPointer); humanData = %str(%addr(temp)); except; dealloc myPointer; // now try it with a procedure pointer: procPtr = %paddr(snprintf); cvthc(rawHexData: %addr(procPtr): %size(rawHexData)); snprintf2(temp: %size(temp): '%p': procPtr); humanData = %str(%addr(temp)); except; // now try it with a teraspace pointer: myPointer = TS_malloc(54321); cvthc(rawHexData: %addr(myPointer): %size(rawHexData)); snprintf(temp: %size(temp): '%p': myPointer); humanData = %str(%addr(temp)); TS_free(myPointer); except; *inlr = *on; /end-free OQSYSPRT E O 'Raw Hex=' O rawHexData +0 O E O 'Human Readable=' O humanData +0
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.