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...
...
...
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.
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:
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...
@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?
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.
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).
SceUID module = sceKernelLoadModule("ms0:/myprx", 0, NULL);
char argument1[256], argument2;
srtcpy(argument1, "The first argument");
strcpy(argument2, "The second argument");
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):
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.
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