Omnimaga

Calculator Community => TI Calculators => Calculator C => Topic started by: compu on August 22, 2011, 03:56:41 pm

Title: Make functions of one program available for other programs?
Post by: compu on August 22, 2011, 03:56:41 pm
When I launch a program via my shell (http://ourl.ca/12605), is it possible to make functions and variables of it available for the launched program?
Title: Re: Make functions of one program available for other programs?
Post by: ExtendeD on August 22, 2011, 04:25:03 pm
Sharing functions dynamically would require dynamic libraries, which is not supported and not really planned in Ndless. But these functions can also be exported as a static library, bound with the program launched at compile time (see how libndls is built and used or bwang's C library somewhere on Omnimaga).

Sharing variables would require a Shared memory, I don't know if the TI-Nspire includes anything like this. A dirty workaround would be to pass the address of a memory block allocated by the shell to the programs launched as a command line parameter, and access the variables relatively to this base address. This could also be used to call back dynamically functions from the shell by the way.
Title: Re: Make functions of one program available for other programs?
Post by: compu on August 24, 2011, 02:42:06 pm
I've tried it on this way now:

I define a structre called _rshellAPI (in a header file that is included in rshell and the launched program) which looks like this:
Code: [Select]
typedef struct _rshellAPI
{
void (*c_draw)(void);
void (*c_clear)(void);
void (*c_writec)(char ch);
void (*c_write)(char* str);
void (*c_swrite)(char* format, int buflen, ...);

char (*cn_readc)(void);
char (*c_readc)(void);

int (*c_read)(char* str);
} rshellAPI;

In rshell's source, I initialize this structure with functions of Nspire I/O (http://nspforge.unsads.com/p/nspireio):
Code: [Select]
rshellAPI rshell =
{
&c_draw,
&c_clear,
&c_writec,
&c_write,
&c_swrite,
&cn_readc,
&c_readc,
&c_read
};

And then pass it to the launched program:
Code: [Select]
((void (*)(int, char **, rshellAPI*))(docptr + sizeof(PRGMSIG)))(n_argc, n_argv, &rshell);
Then I've changed the launched program to use these functions:

Code: (main() definition) [Select]
int main(int argc, char** argv, rshellAPI* rshell)
Code: (example call) [Select]
rshell->c_writec('\n');

All this compiles without errors, but when the launched program tries to call one of the functions, this happens:
Code: [Select]
Error at PC=11140B6C: Unaligned read_word: 11
        Backtrace:
Frame     PrvFrame Self     Return   Start
11136665: 41000000 3A41003A 003E7325 000A0D20
41000000: invalid address

What is wrong with this?
Title: Re: Make functions of one program available for other programs?
Post by: ExtendeD on August 24, 2011, 04:46:55 pm
Does it crash before the call or within the function called?
Title: Re: Make functions of one program available for other programs?
Post by: bsl on August 24, 2011, 07:16:29 pm
Try isolating the problem, see if what you passed is getting there.
They should match.

from the launcner:
printf("n_argc=%i, n_argc=%p, &rshell=%X\n",n_argc, n_argv, &rshell);
((void (*)(int, char **, rshellAPI*))(docptr + sizeof(PRGMSIG)))(n_argc, n_argv, &rshell);


from the launcned:
int main(int argc, char** argv, rshellAPI* rshell){
 printf(argc=%i, argv=%p, rshell=%p\n",argc, argv, rshell);
.
.
.
}

Alignment errors: The adressess in argv, rshell should end in: 0,4,8,C


Declaring with "static" might solve the alignment problem:
static rshellAPI rshell =
{
   &c_draw,
   &c_clear,
   &c_writec,
   &c_write,
   &c_swrite,
   &cn_readc,
   &c_readc,
   &c_read
};
Title: Re: Make functions of one program available for other programs?
Post by: calc84maniac on August 24, 2011, 07:29:57 pm
Do function pointers work properly in the Ndless toolchain? I remember they didn't at some point. What are the GCC options in your makefile?
Title: Re: Make functions of one program available for other programs?
Post by: bsl on August 24, 2011, 07:40:41 pm
Yes, they do.
Look at  ploaderhook.c
Title: Re: Make functions of one program available for other programs?
Post by: ExtendeD on August 25, 2011, 02:24:41 am
Do function pointers work properly in the Ndless toolchain? I remember they didn't at some point. What are the GCC options in your makefile?

Wait, you're right, I forgot that one: http://hackspire.unsads.com/wiki/index.php/Ndless_features_and_limitations#Global_variables
You should use nl_relocdata() on your functions array.
Title: Re: Make functions of one program available for other programs?
Post by: compu on August 25, 2011, 07:33:30 am
First of all, thanks for your help.
Currently I'm not at home, but how do I have to call nl_relocdata() with a structure?
What is the first argument (nl_relocdata_data on Hackspire)?
Title: Re: Make functions of one program available for other programs?
Post by: compu on August 30, 2011, 01:25:33 pm
BUMP

Code: (Launcher) [Select]
n_argc=1, n_argv=1800e070, &rshell=111B0400
Code: (Launched) [Select]
argc=1, argv=1800e070, rshell=00000001
Title: Re: Make functions of one program available for other programs?
Post by: bsl on August 30, 2011, 08:20:03 pm
Try this:
Instead of passing a third argument, just use the last n_argv[19]
to pass the rshell address.
Launcher
Code: [Select]
n_argv[19] = (char*)&rshell; // put pointer in last array slot
Launched
Code: [Select]

int main(int argc, char** argv){
 rshellAPI *rshell;
  rshell = (rshellAPI *)argv[19];
.
.
.
}

Title: Re: Make functions of one program available for other programs?
Post by: compu on August 31, 2011, 02:04:12 am
Doesn't work, but at least the address of rshell in the launched program isn't 00000001 anymore  :-\

I got 2 different errors and one time it just restarted.

Code: (Adresses of argv 19) [Select]
Launcher: 1800e93c
Launched: 111793a8
Title: Re: Make functions of one program available for other programs?
Post by: ExtendeD on September 12, 2011, 01:59:45 pm
First of all, thanks for your help.
Currently I'm not at home, but how do I have to call nl_relocdata() with a structure?
What is the first argument (nl_relocdata_data on Hackspire)?

There was a typo in the sample on Hackspire, it's fixed: http://hackspire.unsads.com/wiki/index.php/Ndless_features_and_limitations#Global_variables
The first argument would be rshell in your case.