Hi all,

I'm having some trouble returning a pointer from an ILE C service
program to a PASE program via the _ILECALLX API on V5R4. I'm getting
the pointer back successfully in my ILEarglist_base structure, but
when I attempt to use _CVTSPP to turn it into a PASE pointer I can use
directly, I'm getting back -1 (FFFFFFFF). The documentation
(http://www-01.ibm.com/support/knowledgecenter/ssw_i5_54/apis/pase__cvtspp.htm)
doesn't list this as a possible return value of this function, so I'm
not sure what to make of it. My service program code is very simple:

const char *return_pointer(){
    static const char *str = "Test string";
    return str;
}

This is compiled into service program JACOBTEST/PTRTEST. This is my
test PASE program I wrote to call it:

#include <as400_protos.h>
#include <as400_types.h>
#include <iconv.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv){
    unsigned long long actmark;
    ILEpointer *invptr = malloc(sizeof(ILEpointer)), *textptr =
malloc(sizeof(ILEpointer));
    arg_type_t arg_types[] = {ARG_END};
    result_type_t result_type = 16;
    ILEarglist_base *ile_arglist = malloc(size_ILEarglist(arg_types));
    void *parameters[] = {NULL};
    void *resultptr = NULL;
    char text[32767];
    char ascii[32767];
    iconv_t converter = iconv_open("ISO8859-1", "IBM-037");
    size_t src_len = sizeof(text);
    size_t dest_len = sizeof(ascii);
    const char *src = text;
    char *dest = ascii;

    build_ILEarglist(ile_arglist, parameters, arg_types);
    actmark = _ILELOADX("JACOBTEST/PTRTEST", ILELOAD_LIBOBJ);
    _ILESYMX(invptr, actmark, "return_pointer");
    _ILECALLX(invptr, ile_arglist, arg_types, result_type, 0);

    printf("%016llX%016llX\n", *(address64_t
*)&ile_arglist->result.r_aggregate, *(((address64_t
*)&ile_arglist->result.r_aggregate)+1));
    resultptr = _CVTSPP(&ile_arglist->result.r_aggregate);
    printf("%p\n", resultptr);
    memset(text, 0, sizeof(text));
    _SETSPP(textptr, text);
    _STRNCPY_SPP(textptr, &ile_arglist->result.r_aggregate,
_STRLEN_SPP(&ile_arglist->result.r_aggregate));
    iconv(converter, &src, &src_len, &dest, &dest_len);
    printf("%s\n", ascii);

    iconv_close(converter);
    free(invptr);
    free(textptr);
    free(ile_arglist);
    return 0;
}

I compile this with GCC 4.2. When I run it, I get the following output:

8000000000000000D1067B82A4056C90
ffffffff
Test string

The first line is the 16-byte space pointer being returned in the
result member of the ILEarglist_base structure, which matches what I
see if I put the service program in debug and display the value of
str. On the second line, I can see that _CVTSPP is returning FFFFFFFF
instead of a valid PASE pointer. However, on the third line, I'm still
able to use the _STRNCPY_SPP and _STRLEN_SPP APIs to copy the data
with the original space pointer, convert it to ASCII, and display it,
which seems to me to indicate that the pointer is good.

Does anyone who has experience with these APIs see if I'm doing
anything wrong here? It's simple enough in my test program to copy the
string, but in practice I'd rather not have to copy the data pointed
to by the pointer that's being returned to me. I wondered if maybe a
copy was going on behind the scenes and destroying the tag bits in the
pointer, but if that were the case I wouldn't expect _STRNCPY_SPP and
_STRLEN_SPP to work. Any advice is greatly appreciated.

Thanks,

Jacob Smallwood

As an Amazon Associate we earn from qualifying purchases.

This thread ...


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

This mailing list archive is Copyright 1997-2022 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.