Natural Native Interfaces and NATUSER

Hey,

I’m playing around a little bit with the Natural Native Interfaces. In theory everything work but when i want to load a sharedlibrary over the NATUSER enviroment variable i get a Natural Startup Error 26.
When i load the sharedlibrary over the normal natural binary everything works fine.

I have tried to get more informations about the startup process with the NATLOG parameter but even in the logfile stands only this:

Is there any way to get more informations what goes wrong? (Yes the file exist and the user can read it. I have checked this.)

Here is my example Code from the NNI:


#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

#include "natni.h"
#include "natuser.h"

#define NAT_LIB_NAME "libnatural.so"
#define GET_INTERFACE_FUNC "nni_get_interface"
#define LOGON_LIB "TGAP0734"
#define TEST_PROG "SSHUS"

void printNaturalException( struct natural_exception *pnatexcep );
int OpenLib(void **shLib, char *name);
void CloseLib(void **shLib);

int main()
{
    void *shlib = NULL;
    char *error;
    char tmp_buff[1024];
    int rc, i;
    PF_NNI_GET_INTERFACE pf_nni_get_interface = 0;
    pnni_611_functions s_func;
    struct natural_exception nat_ex;
    struct parameter_description params[5];
    void *phandle = NULL;
    int ind[3] = {0, 0, 0}; 
    int occ[3] = {0, 0, 0};


    if(OpenLib(&shlib, NAT_LIB_NAME) < 0)
    {
        exit();
    }

    printf("Done Loading. Pointer: %p\n", shlib);

    pf_nni_get_interface = (PF_NNI_GET_INTERFACE)dlsym(shlib,
        GET_INTERFACE_FUNC);

    if(!pf_nni_get_interface)
    {
        error = dlerror();
        printf("Error while loading Function [%s]: [%s]\n", GET_INTERFACE_FUNC,
            error);
        CloseLib(&shlib);
        exit();
    }

    //Get Function Table
    printf("Get Function Table...");
    if(((pf_nni_get_interface)(NNI_VERSION_CURR, (void**)&s_func)) != NNI_RC_OK)
    {
        printf("...Error while gettings Functrion Table\n");
        CloseLib(&shlib);
        exit();
    }
    printf("...Done\n");

    //Initialize Natural session
    printf("Init Natural Session...");
    if(s_func->pf_nni_initialize(s_func, "parm=logiparm etid=&& NATLOG=ALL", 0, 0) != NNI_RC_OK)
    {
        printf("...Error\n");
        CloseLib(&shlib);
        exit();
    }
    printf("...Done\n");

    //Logon into tgap0734
    printf("Logon into [%s]...", LOGON_LIB);
    if((rc = s_func->pf_nni_logon(s_func, LOGON_LIB, 0, 0)) != NNI_RC_OK)
    {
        printf("...Error. Nr: [%d]\n", rc);
        CloseLib(&shlib);
        exit();
    }
    printf("...Done\n");

    s_func->pf_nni_create_parm(s_func, 5, &phandle);

    occ[0] = 20;
    s_func->pf_nni_init_parm_sa(s_func, 0, phandle, 'A', 15, 0, 1, occ, 0);
    s_func->pf_nni_init_parm_sa(s_func, 1, phandle, 'A', 20, 0, 1, occ, 0);
    s_func->pf_nni_init_parm_s(s_func, 2, phandle, 'A', 5, 0, 0);
    s_func->pf_nni_init_parm_s(s_func, 3, phandle, 'A', 100, 0, 0);
    s_func->pf_nni_init_parm_d(s_func, 4, phandle, 'A', 0);

    for(ind[0]=0; ind[0] < occ[0]; ind[0]++)
    {
        sprintf(tmp_buff, "value %d", i);
        s_func->pf_nni_put_parm_array(s_func, 0, phandle, 1024, tmp_buff, ind);

        sprintf(tmp_buff, "key %d", i);
        s_func->pf_nni_put_parm_array(s_func, 1, phandle, 1024, tmp_buff, ind);
    }

    strcpy(tmp_buff, "GET");
    s_func->pf_nni_put_parm(s_func, 2, phandle, 1024, tmp_buff);

    strcpy(tmp_buff, "/tmp/outputtest.html");
    s_func->pf_nni_put_parm(s_func, 3, phandle, 1024, tmp_buff);

    strcpy(tmp_buff, "test=ok");
    s_func->pf_nni_put_parm(s_func, 4, phandle, 1024, tmp_buff);

    for(i=0; i < 5; i++)
    {
        s_func->pf_nni_get_parm_info(s_func, i, phandle, &params[i]);
    }


    //Call Subprog with no parms
    printf("Call subprogramm [%s]...", TEST_PROG);
    if(s_func->pf_nni_callnat(s_func, TEST_PROG, 5, params, &nat_ex) != NNI_RC_OK)
    {
        printf("...Error\n");
        printNaturalException(&nat_ex);
        CloseLib(&shlib);
        exit();
    }
    printf("...Done\n");


    printf( "Uninitializing Natural..." );
    s_func->pf_nni_uninitialize(s_func);
    printf("...Done\n");

    printf("Freeing interface...");
    s_func->pf_nni_free_interface(s_func);
    printf("...Done\n");

    CloseLib(&shlib);

}

int OpenLib(void **shLib, char *name)
{
    char *error;

    *shLib = dlopen(name, RTLD_NOW);
    if(!*shLib)
    {
        error = dlerror();
        printf("Error while loading Module [%s]: [%s]\n", name, error);
        return(-1);
    }
    return(0);
}

void CloseLib(void **shLib)
{
    dlclose(*shLib);
}



/* Format and print a Natural exception. */
void printNaturalException( struct natural_exception *pnatexcep )
{
    if (pnatexcep)
    {
        printf( "MessageNumber: %d.\n",
            pnatexcep->natMessageNumber );
        printf( "MessageText:   %s\n",
            pnatexcep->natMessageText ? pnatexcep->natMessageText : "0" );
        printf( "Library:       %s.\n",
            pnatexcep->natLibrary ? pnatexcep->natLibrary : "0" );
        printf( "Member:        %s.\n",
            pnatexcep->natMember ? pnatexcep->natMember : "0" );
        printf( "Name:          %s.\n",
            pnatexcep->natName ? pnatexcep->natName : "0" );
        printf( "Method:        %s.\n",
            pnatexcep->natMethod ? pnatexcep->natMethod : "0" );
        printf( "Line:          %d.\n",
            pnatexcep->natLine );
    }
}

And here is the code from the sharedlibrary:


#include <stdio.h>
#include <stdlib.h>

#include "natuser.h"

long user_exit(WORD nparm, void *parmhandle, void *traditional)
{
    return(0);
}