#emit & return - Invalid memory access -
Su37Erich - 07.08.2016
Hello everyone,
I am requesting help with a function to format a local string with x arguments, the string have already the %s %d characters. Here is it:
Code:
getMessageA(const playerid, const key[], { Float, _ }: ...)
{
new value[144];
//Some stuff
GetGVarString(key2, value);//Value is the string I want to format, it's a local variable as you can see. I had it as an static variable but it was causing the same error that the return causes now (Invalid memory access)
new args = (numargs() - 3) << 2;
if(args)
{
static s_szBuf[144], s_iAddr1, s_iAddr2;//Using s_szBuf as "new" crashes the server
#emit ADDR.PRI value
#emit STOR.PRI s_iAddr1
for(s_iAddr2 = s_iAddr1 + args, args += 12; s_iAddr2 != s_iAddr1; s_iAddr2 -= 4)
{
#emit LOAD.PRI s_iAddr2
#emit LOAD.I
#emit PUSH.PRI
}
#emit CONST.PRI s_szBuf
#emit PUSH.S value
#emit PUSH.C 144
#emit PUSH.PRI
#emit PUSH.S args
#emit SYSREQ.C format
#emit LCTRL 4
#emit LOAD.S.ALT args
#emit ADD.C 4
#emit ADD
#emit SCTRL 4
return s_szBuf;//This is line 165
}
return value;
}
I get:
[18:19:39] [debug] Run time error 5: "Invalid memory access"
[18:19:39] [debug] AMX backtrace:
[18:19:39] [debug] #0 00009f78 in getMessageA(playerid=0, key[]=@0001ef50 "SURHAVE", ... <2 arguments>) at C:blah\pawno\include\language.inc:165
[18:19:39] [debug] #1 0000a5a4 in main () at GM.pwn:196
[18:19:39] Script[gamemodes/GM.amx]: Run time error 5: "Invalid memory access"
I have a sendMessage function like this and it is working fine:
Code:
stock sendMessage(const iPlayer, const iColor, const szFormat[], { Float, _ }: ...)
{
new iArgs = (numargs() - 3) << 2;
if(iArgs)
{
static s_szBuf[144], s_iAddr1, s_iAddr2;
#emit ADDR.PRI szFormat
#emit STOR.PRI s_iAddr1
for(s_iAddr2 = s_iAddr1 + iArgs, iArgs += 12; s_iAddr2 != s_iAddr1; s_iAddr2 -= 4)
{
#emit LOAD.PRI s_iAddr2
#emit LOAD.I
#emit PUSH.PRI
}
#emit CONST.PRI s_szBuf
#emit PUSH.S szFormat
#emit PUSH.C 144
#emit PUSH.PRI
#emit PUSH.S iArgs
#emit SYSREQ.C format
#emit LCTRL 4
#emit LOAD.S.ALT iArgs
#emit ADD.C 4
#emit ADD
#emit SCTRL 4
return (iPlayer != -1) ? SendClientMessage(iPlayer, iColor, s_szBuf) : SendClientMessageToAll(iColor, s_szBuf);
}
return (iPlayer != -1) ? SendClientMessage(iPlayer, iColor, szFormat) : SendClientMessageToAll(iColor, szFormat);
}
I don't get it

I am not familiar with #emit
Re: #emit & return - Invalid memory access -
Misiur - 07.08.2016
In getMessageA:
pawn Code:
//Change this:
new args = (numargs() - 3) << 2;
//To this:
new args = (numargs() - 2) << 2;
Why? Well, your sendMessage has 3 parameters before the variable arguments, while getMessageA has only 2.
Respuesta: #emit & return - Invalid memory access -
Su37Erich - 07.08.2016
Thank you Misiur, it should fix a lot of things, unfortunately the error is still there, I think it is related with the AMX memory? but I can't figure what I must edit
Re: #emit & return - Invalid memory access -
Misiur - 08.08.2016
Yup, I can see few more problems, such as loading "ADDR.PRI value" - you want "ADDR.PRI key" there. I have to sleep now, but if nobody helps you before I get up I'll try to fiddle around some more.
Re: #emit & return - Invalid memory access -
Misiur - 09.08.2016
pawn Code:
stock getMessageA(const key[], { Float, _ }: ...)
{
static value[144];
GetGVarString(key, value);
new args = (numargs() - 1) << 2;
if(args)
{
static s_szBuf[144], s_iAddr1, s_iAddr2;
#emit ADDR.PRI key
#emit STOR.PRI s_iAddr1
for(s_iAddr2 = s_iAddr1 + args, args += 12; s_iAddr2 != s_iAddr1; s_iAddr2 -= 4)
{
#emit LOAD.PRI s_iAddr2
#emit LOAD.I
#emit PUSH.PRI
}
#emit CONST.PRI s_szBuf
#emit PUSH.C value
#emit PUSH.C 144
#emit PUSH.PRI
#emit PUSH.S args
#emit SYSREQ.C format
#emit LCTRL 4
#emit LOAD.S.ALT args
#emit ADD.C 4
#emit ADD
#emit SCTRL 4
return s_szBuf;//This is line 165
}
return value;
}
For some reason I had to change value to static, because when I did normal PUSH.S the string got mangled somehow, but with PUSH.C works. Weird. Anyway: if you're using YSI, there's y_va library, which is as easy as
pawn Code:
YouFunction(const key[], va_args<>) {
new value[144], result[144];
GetGVarString(key, value);
va_format(result, sizeof result, value, va_start<1>);
return result;
}