[C++] Comincazione veloce DLL/GM

Gex, Dll, DyLib, Js e ogni tipo di estensione per GameMaker
Rispondi
Avatar utente
Sla
GMI VIP
Messaggi: 3618
Iscritto il: 21/07/2008, 10:11
Specialità: Titanismo
Località: (gm) Italia
Contatta:

[C++] Comincazione veloce DLL/GM

Messaggio da Sla »

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.

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);
}
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*.

Codice: Seleziona tutto

variabile = "vediamo se questo sistema funziona, probabilmente sì";
FindAddress(variabile);
Potete modificare il valore della variabile di gm accedendo all'indirizzo come fareste normalmente..

Codice: Seleziona tutto

char* addy = (char*)indirizzo_ritornato_da_FindAddress;
char* nuovo_valore = "nuova stringa!!";
memcpy(addy,nuovo_valore,strlen(nuovo_valore)+1);
ricordandovi sempre di null-terminare la stringa.

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();
}
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.
eppure mi sembra tutto giusto...

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Jak »

Mooooooolto interessante :fapensare:
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Avatar utente
BaronVsCorsar
GMI VIP
Messaggi: 4699
Iscritto il: 14/02/2004, 12:05
Specialità: Saccenza
Uso: GameMaker 8.1
Località: Ferrara
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da BaronVsCorsar »

e anche molto "pericoloso" (a livello di bug inseriti/ difficoltà a debuggare).
è davvero così lento la chiamata a dll da gm?
e soprattutto, non perdo i vantaggi appesantendo il tutto con un ciclo della dll?
Forse una dll come la slad3d, che in pratica un ciclo suo lo deve avere...
Suppongo che per sfruttare questo metodo dal programma GM si debba comandare la dll tramite variabili di "sola lettura" giusto? Se chiamo funzioni dll nel metodo normale perdo tutto il vantaggio no?

hai fatto delle prove su quanto sia più veloce?


e offtopic e per curiosità: quanti sono i produttori di dll su gmi?
ImmagineSchiva questo - http:\\baronvscorsar.altervista.org
by Lego: Vado in un bar e faccio "votiamo che quel tizio la in fondo venga buttato fuori", ma perché?

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Jak »

Bè, però sarebbe una grande velocizzazione nel maneggiamento dei dati poichè non devi gestire alcuna informazione in alcun modo da parte dll. Sarebbe molto utile quando devi maneggiare una grande mole di dati che in gml sarebbe molto lento(come ad esempio lasciando fare i calcoli per il light engine alle ds_grid anzichè a game maker con codice fatto in casa è risultato mooooooolto più veloce). Dopotutto eviti la lettura e la scrittura dei dati.
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Avatar utente
Tizzio
GMI Honor
Messaggi: 5836
Iscritto il: 29/06/2010, 23:43
Specialità: programmazione
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Tizzio »

Slascio, dato che puoi ottenere l'indirizzo di una variabile
Non sarebbe possibile ottenere l'indirizzo di una surface?

Codice: Seleziona tutto

s=surface_create();
FindAddress(s,"type_surface");
aggiungendo un argomento che definisce il tipo di variabile trasmessa(in questo caso una surface).
e nella dll drawware su quella surface.
Si potrebbe fare una cosa simile?

Ps: te lo chiedo perchè GMAPI non mi funziona (neanche gli esempi dati), e volevo implementare una dll che drawwi ogni step su una surface di gm senza usare files esterni.

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Jak »

BaronVsCorsar ha scritto:e offtopic e per curiosità: quanti sono i produttori di dll su gmi?
Ops, dimenticavo.
Bè, oltre a slascio io me la cavicchio(anche se so ancora poco di c++) ed inoltre mi pare(mi pare) che anche qualcun'altro tipo nix sappia farle.
Tuttavia effettivamente si vedono ben poche dll su GMI(e fatte quasi tutte da slascio) :fapensare:
Ho deciso, ora mi ci metto e faccio le ds cube :sisisi:
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Nix
GMI Advanced
Messaggi: 2437
Iscritto il: 26/12/2008, 18:14
Uso: GM:Studio 2
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Nix »

Tizzio ha scritto:Slascio, dato che puoi ottenere l'indirizzo di una variabile
Non sarebbe possibile ottenere l'indirizzo di una surface?
Non con questo sistema, surface_create restituisce un indice :fapensare:
Jak ha scritto:anche qualcun'altro tipo nix sappia farle.
[spam+ot]
Sì, ne sto facendo una: http://ziocrocifisso.altervista.org/nsdll/html/
[/spam+ot]

Avatar utente
Sla
GMI VIP
Messaggi: 3618
Iscritto il: 21/07/2008, 10:11
Specialità: Titanismo
Località: (gm) Italia
Contatta:

Re: [C++] Comincazione veloce DLL/GM

Messaggio da Sla »

Ah, noto solo ora le risposte.
Se si vuole rimpiazzare l'intero sistema di richiamo a funzioni di GM effettivamente è più conveniente che la DLL debba per forza avere un proprio ciclo.
L'utilizzo più comune, altrimenti, sarebbe al di fuori di un ciclo per passare grandi moli di informazioni a gm, operazione che con questa tecnica risulterebbe nettamente più
veloce della lettura di un valore di ritorno di una funzione richiamata dalla DLL.
Non c'è bisogno di test: la velocità è quella di allocazione di memoria del processo che esegue la DLL.
eppure mi sembra tutto giusto...

Rispondi

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti