[C++] Comincazione veloce DLL/GM
Inviato: 15/01/2012, 22:25
Se state creando una DLL potrebbe sicuramente interessarvi questo sistema (in C/C++) per velocizzare le comunicazioni gm -> dll e dll -> gm, che evita di
dover effettuare un richiamo a funzione della DLL per passare qualche informazione.
In pratica la DLL trova l'indirizzo di una variabile stringa di game maker ed è in seguito in grado di modificare il valore della variabile stessa quando vuole.
da GM potrete controllare il valore della variabile per vedere se è arrivato un "messaggio" dalla DLL.
Per mandare un messaggio da GM alla DLL potete ad esempio creare una seconda variabile che verrà solamente monitorata dalla DLL.
In Game Maker create una variabile e le attribuite un valore stringa lungo (è importante: quando la DLL andrà a modificare la variabile il nuovo
valore non potrà essere più lungo di quello iniziale) e unico (che non abbiate usato per altre variabili).
esempio:
variabile = "vediamo se questo sistema funziona, probabilmente sì";
chiamate FindAddress passandogli quello stesso valore stringa. FindAddress esaminerà la memoria del processo e troverà l'indirizzo che contiene quel valore, ritornandolo come void*.
Potete modificare il valore della variabile di gm accedendo all'indirizzo come fareste normalmente..
ricordandovi sempre di null-terminare la stringa.
Potete monitorare una variabile di gm in questo modo:
Volendo potete rimpiazzare l'intero sistema di richiamo delle funzioni di dll di gm con questo.
Dovete chiaramente dotare la DLL di un ciclo suo, e potete farlo dalla funzione EntryPoint (DllMain), che ricordo viene chiamata
una sola volta da GM quando viene definita la prima funzione con external_define.
dover effettuare un richiamo a funzione della DLL per passare qualche informazione.
In pratica la DLL trova l'indirizzo di una variabile stringa di game maker ed è in seguito in grado di modificare il valore della variabile stessa quando vuole.
da GM potrete controllare il valore della variabile per vedere se è arrivato un "messaggio" dalla DLL.
Per mandare un messaggio da GM alla DLL potete ad esempio creare una seconda variabile che verrà solamente monitorata dalla DLL.
Codice: Seleziona tutto
#define MAX 800
void* FindAddress(char* var_value)
{
MEMORY_BASIC_INFORMATION* info = new MEMORY_BASIC_INFORMATION[MAX];
SIZE_T sz = sizeof(MEMORY_BASIC_INFORMATION);
int cnt = 0;
char* BaseAddress = NULL;
int offset = VirtualQuery(NULL,info,MAX*sizeof(MEMORY_BASIC_INFORMATION));
offset /= sizeof(MEMORY_BASIC_INFORMATION);
BaseAddress += info[cnt].RegionSize;
cnt += offset;
int i;
while(sz >= sizeof(MEMORY_BASIC_INFORMATION))
{
sz = VirtualQuery(BaseAddress,&info[cnt],(MAX-cnt)*sizeof(MEMORY_BASIC_INFORMATION));
offset = sz/sizeof(MEMORY_BASIC_INFORMATION);
for(i=0;i<offset;i++)
BaseAddress += info[cnt+i].RegionSize;
cnt += offset;
}
//NOW SEARCH FOR MY STRING
char* found_address;
bool found;
for(i=0;i<cnt;i++)
{
if(info[i].State != MEM_COMMIT) continue;
found_address = (char*)info[i].BaseAddress;
found = false;
while( (int)found_address - (int)info[i].BaseAddress < info[i].RegionSize-sizeof(char*) )
{
//Analyze address
if(strcmp(var_value,found_address) == 0)
{
found = true;
break;
}
//Proceed to next address
found_address++;
}
if(found) break;
}
return((void*)found_address);
}
valore non potrà essere più lungo di quello iniziale) e unico (che non abbiate usato per altre variabili).
esempio:
variabile = "vediamo se questo sistema funziona, probabilmente sì";
chiamate FindAddress passandogli quello stesso valore stringa. FindAddress esaminerà la memoria del processo e troverà l'indirizzo che contiene quel valore, ritornandolo come void*.
Codice: Seleziona tutto
variabile = "vediamo se questo sistema funziona, probabilmente sì";
FindAddress(variabile);
Codice: Seleziona tutto
char* addy = (char*)indirizzo_ritornato_da_FindAddress;
char* nuovo_valore = "nuova stringa!!";
memcpy(addy,nuovo_valore,strlen(nuovo_valore)+1);
Potete monitorare una variabile di gm in questo modo:
Codice: Seleziona tutto
if(strcmp((char*)indirizzo_ritornato_da_FindAddress,"Valore") == 0) //la variabile di gm corrisponde a "Valore"
{
FaiQuesto();
}
Dovete chiaramente dotare la DLL di un ciclo suo, e potete farlo dalla funzione EntryPoint (DllMain), che ricordo viene chiamata
una sola volta da GM quando viene definita la prima funzione con external_define.