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, ¶ms[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);
}