forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] Start a module with more than one argument...

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
darkness



Joined: 15 Jun 2008
Posts: 121

PostPosted: Sat Jun 28, 2008 10:27 pm    Post subject: [SOLVED] Start a module with more than one argument... Reply with quote

Excuse me,
I'm trying to start a prx with more than one args but I don't know the argp structure, so if is possible, how to do this?
I've think to write the ars in different position but the args is not a simple string...
Here is a sample...
Code:

...
...
strcpy(argp, "First Argument");
char* args2="Second Argument";

int a;
for(a=0; a<=strlen(args2); a++)
{
     argp[50+a]=args2[a]; // <---- I cannot do this, is a sample of I want to do...
     
}


...
...

sceKernelStartModule(mod, strlen(argp)+1, argp, NULL, NULL);

This is a sample of I want to do, so can anyone help me? :)
Thanks in advance!!


Last edited by darkness on Mon Jul 07, 2008 2:32 am; edited 1 time in total
Back to top
View user's profile Send private message
Pirata Nervo



Joined: 09 Oct 2007
Posts: 409

PostPosted: Sat Jun 28, 2008 11:27 pm    Post subject: Reply with quote

first, argp is not a structure, it's a pointer to the arguments. (as far as I know)
I don't really understand what you want.

I think what you want is this. (to pass the argument)

Code:
SceUID module = sceKernelLoadModule("ms0:/myprx", 0, NULL);

void * argumentP = NULL;

argumentP[0] = mystring1;
argumentP[1] = mystring2;

int status;

sceKernelStartModule(module,(strlen(mystring1)+1)+(strlen(mystring2)+1), argumentP, &status, NULL); // pass the first argument as NULL or as a SceKernelSMOption structure


I don't know if that will work tho. (didn't test it)

To get the argumentP[0] and argumentP[1], use this inside the loaded prx:
Code:
char mystring1[255], mystring2[255];
strcpy(mystring1, (char*)argp[0]);
strcpy(mystring2, (char*)argp[1]);


As I said I didn't test it and I don't know if it works or not
_________________

Upgrade your PSP
Back to top
View user's profile Send private message
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Sat Jun 28, 2008 11:49 pm    Post subject: Reply with quote

As PN said args is not a struct but a pointer. However, it is a good idea to use a pointer to structure holding other types if you need to pass multiple arguments. If you don't know in advance how many parameters to pass, then a "bad design" bell should sound in your mind. In very rare and special case this is required and implemented through collections. Sorry, no demo code...however you now got the buzzwords.
PS: code by PN should not work...array must be initialized as local or allocated so that argumentP[...] can avoid write in not allocated area or onto other stack variables...
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sat Jun 28, 2008 11:56 pm    Post subject: Reply with quote

not exactly. I think it would be something like :

Code:

SceUID module = sceKernelLoadModule("ms0:/myprx", 0, NULL);

char data[256*n];

int size = 0;

for (i = 0; i < n; ++i)
{
    strncpy(data+size, str[i], 255);
    size += strlen(str[i]) + 1;
}

int status;

sceKernelStartModule(module,size, (void *)data, &status, NULL);


to retrieve them
Code:

char str[n*256];

char *data = (char *)argp;

int size = 0;

for (i = 0; i < n; ++i)
{
    strncpy(str[i], data+size, 255);
    size += strlen(data+size) + 1;
}
Back to top
View user's profile Send private message
Pirata Nervo



Joined: 09 Oct 2007
Posts: 409

PostPosted: Sun Jun 29, 2008 12:05 am    Post subject: Reply with quote

@jean, yeh as I predicted it would not work :P
I wrote a very simple way but would not work.
Yeh I forgot to allocate the void pointer data
@hlide, where does the str variable come from?
_________________

Upgrade your PSP
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sun Jun 29, 2008 12:06 am    Post subject: Reply with quote

if i'm not wrong, for the function which receives argp and args, there is always a copy of the content pointed by argp passed to sceKernelStartModulemust and args should get the bytes length to copy, so the contents couldn't be a structure with pointers.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sun Jun 29, 2008 12:12 am    Post subject: Reply with quote

Pirata Nervo wrote:
@hlide, where does the str variable come from?


i wrote this code for a variable number of string to pass, str is just your array of string you want to pass (I replaced your mystring1, mystring2 for n = 2).

you need to coalesce your strings into one flat string where string separator is a null string '\0' to handle it as a flat block and pass the total size of this block (null separators included).
Back to top
View user's profile Send private message
Pirata Nervo



Joined: 09 Oct 2007
Posts: 409

PostPosted: Sun Jun 29, 2008 12:15 am    Post subject: Reply with quote

Yeh I understand what you mean :)
I do it on my program but didn't bother to open the file which passes arguments to a pbp
_________________

Upgrade your PSP
Back to top
View user's profile Send private message
darkness



Joined: 15 Jun 2008
Posts: 121

PostPosted: Sun Jun 29, 2008 12:35 am    Post subject: Reply with quote

Excuse me, but I haven't understand very well the code of hlide:
Code:

SceUID module = sceKernelLoadModule("ms0:/myprx", 0, NULL);

char argument1[256], argument2;
srtcpy(argument1, "The first argument");
strcpy(argument2, "The second argument");

And I've to put theese two string into srt?
Code:


char data[256*n];

int size = 0;

for (i = 0; i < n; ++i)
{
    strncpy(data+size, str[i], 255);
    size += strlen(str[i]) + 1;
}

int status;

sceKernelStartModule(module,size, (void *)data, &status, NULL);

to retrieve them:
Code:

char str[n*256];

char *data = (char *)argp;

int size = 0;

for (i = 0; i < n; ++i)
{
    strncpy(str[i], data+size, 255);
    size += strlen(data+size) + 1;
}

But where is the results args? into srt separated by \0?
Excuse me please, but I'm doing a lot of confusion...
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sun Jun 29, 2008 12:59 am    Post subject: Reply with quote

what do you need ? two strings to pass ?

Code:

SceUID module = sceKernelLoadModule("ms0:/myprx", 0, NULL);

char data[256*2];

char *str1 = "my 1st argument";
char *str2 = "my 2nd argument";

int len1 = strlen(str1);
int len2 = strlen(str2);

strncpy(data, str1, 255);
strncpy(data+len1+1, str2, 255);

int status;

sceKernelStartModule(module, len1+len2+2, (void *)data, &status, NULL);


in your start module of your PRX
Code:

char str[2*256];

char *data = (char *)argp;

int size = 0;

for (i = 0; i < 2; ++i)
{
    strncpy(str[i], data+size, 255);
    size += strlen(data+size) + 1;
}


str[0] <--- "my 1st argument"
str[1] <--- "my 2nd argument"
Back to top
View user's profile Send private message
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Sun Jun 29, 2008 1:12 am    Post subject: Reply with quote

Well as pointed out what happens when you call StartModule (and StartThread as it happens) is the kernel copies args bytes from the argp pointer to the top of the initial thread's stack, it then calls the entry point passing you a pointer to the data on the stack.

There is nothing stopping you passing anything you across, in fact no reason you cannot pass pointers (assuming you can access the memory in the new prx) just you have to ensure that the memory that points to is valid.

Ultimately it is up to you to decide how best to encode your data so you can unpack it again at the other side.

To convert between say standard style argc/argv you could do something like this (bad code warning :P):
Code:
int build_args(char *args, int argc, char **argv)
{   
    int loc = 0;
    int i;
   
    for(i = 0; i < argc; i++)
    {   
        strcpy(&args[loc], argv[i]);
        loc += strlen(argv[i]) + 1;
    }
   
    return loc;
}

int unpack_args(char *argp, int args, char **argv)
{
    int loc = 0;
    int argc = 0;

    *argc = 0;
    while(loc < args)
    {
        argv[argc++] = &argp[loc];
        loc += strlen(&argp[loc]) + 1;
    }
    argv[argc] = NULL;

    return argc;
}   

/* To pack the args for StartModule */
char argp[1024];
char **argv = { {"1"}, {"2"}, {"3"} };
args = build_args(argp, 3, argv);

/* Unpack them at the other side */
char* argv[16];
int argc;
argc = unpack_args(argp, args, argv);
Back to top
View user's profile Send private message
darkness



Joined: 15 Jun 2008
Posts: 121

PostPosted: Sun Jun 29, 2008 1:28 am    Post subject: Reply with quote

Thanks very much...

EDIT:
puff, If I try to compile this code I have a lot of errors...
I'll use the hlide solution...


Last edited by darkness on Sun Jun 29, 2008 1:55 am; edited 2 times in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sun Jun 29, 2008 1:28 am    Post subject: Reply with quote

TyRaNiD wrote:
There is nothing stopping you passing anything you across, in fact no reason you cannot pass pointers (assuming you can access the memory in the new prx) just you have to ensure that the memory that points to is valid.

true but I preferred not to advise to do so. We could fear a lot of posts wondering why "my app crashes when I load my PRX ?" because someone is freeing some passed structures in argp while a PRX is using them for instance.

so kids, avoid doing so if you don't want big headaches ! especially if you don't know what you do.
Back to top
View user's profile Send private message
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Sun Jun 29, 2008 9:23 am    Post subject: Reply with quote

Well the same argument could be made for any args passed to a prx above and beyond simple argc/argv style stuff.
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Mon Jun 30, 2008 1:05 am    Post subject: Reply with quote

TyRaNiD wrote:

To convert between say standard style argc/argv you could do something like this (bad code warning :P):
Code:
int build_args(char *args, int argc, char **argv)
{   
    int loc = 0;
    int i;
   
    for(i = 0; i < argc; i++)
    {   
        strcpy(&args[loc], argv[i]);
        loc += strlen(argv[i]) + 1;
    }
   
    return loc;
}

int unpack_args(char *argp, int args, char **argv)
{
    int loc = 0;
    int argc = 0;

    *argc = 0;
    while(loc < args)
    {
        argv[argc++] = &argp[loc];
        loc += strlen(&argp[loc]) + 1;
    }
    argv[argc] = NULL;

    return argc;
}   

/* To pack the args for StartModule */
char argp[1024];
char **argv = { {"1"}, {"2"}, {"3"} };
args = build_args(argp, 3, argv);

/* Unpack them at the other side */
char* argv[16];
int argc;
argc = unpack_args(argp, args, argv);


I want to mix and match between the length/*args combo that modules use, and the argc,**argv.

The above functions screw up sometimes depending on the contents of length/*args (presumably due to the presence of NULL characters which breaks strcpy).

I feel the ideal solution is to ALWAYS use only length/*args like modules use. Thats what the SCE functions use anyway.

How do you make an EBOOT that uses length/*args?
int main() only works with argc/**argv
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group