Memory shared e accesso dati attraverso un applicazione C#

venerdì 26 settembre 2008 - 16.09

beguroto Profilo | Junior Member

Un saluto a tutti,
sto iniziando da autodidatta un progetto che da tempo ho in mente di realizzare. In pratica vorrei realizzare un sistema di controllo che vada a leggere lo stato di alcune variabili settabili da utente e aggiornarle in real time:
1) Vorrei creare un programmino in C# che apra un database (per esempio un database Access) contenente un serie di variabili e vada a salvarle su una shared memory
2) Creare un software C# che vada a leggere queste variabili in real time dalla memoria condivisa e le rappresenti su un grafico X,Y

Qualcuno sa darmi qualche dritta su come salvare variabili su una memoria condivisa e richiamarle da una seconda o terza applicazione?
Come faccio a fa capire alla mia applicazione dove trovare queste variabili?
C'è una guida o un libro sul quale posso chiarire i miei dubbi?

Ogni commenti e suggerimento è ben accettato!!!
Vi ringrazio in anticipo :-)

schifidus Profilo | Junior Member

Cosa intendi con Shared Memory?
Non possono accedere al DB le applicazioni e leggere le variabili da li?
Marco Farina
MCTS .NET Framework 2.0 Web Applications
MCPD Web Applications

beguroto Profilo | Junior Member

Spiego meglio la mia situazione:
Ho un software 1 che costantemente è in esecuzione sul mio pc che acquisisce variabili dall' esterno tramite seriale. Vorrei crearmi un software 2 che va a leggere le variabili acquisite dal software1 e le mostra a scherm su dei charts. ( Il daatbase lo uso esclusivamente all' avvio del software1 per configurare le variabili da acquisire...)
Come posso fare per "raggiungere" le variabili del software 1 e mostrarle a monitor tramite software2?
E' possibile tramite il software 2 forzare il valore delle variabili del software1?

Vi ringrazio in anticipo per l' aiuto..

Begs

aiedail92 Profilo | Expert

Ciao, ho visto che hai chiesto aiuto anche sull'altro thread, ti rispondo qui

Per fare quello che devi fare devi usare le API di Windows, in particolare VirtualAlloc per allocare della memoria non gestita, e ReadProcessMemory per leggere la memoria di un processo "straniero".

Eccoti un esempio di cosa dovresti fare sul processo1, quello che elabora i dati:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

La prima cosa da fare è chiamare InitSharedMem per inizializzare la memoria condivisa e i puntatori nel registro. In seguito per ogni passo di elaborazione devi chiamare la funzione Elabora, che elabora i dati e li salva nella memoria condivisa, preoccupandosi anche di aggiornarli se specificato da altri processi. Quando hai finito di usare il processo, prima di chiudere l'applicazione, deve essere chiamato il metodo CleanUp per rilasciare la memoria condivisa ed eliminare le chiavi del registro.

Questo invece è il codice da inserire nella seconda applicazione per leggere i dati esposti nella prima. Nota che la struttura SharedData deve essere definita nel medesimo modo in entrambe le applicazioni, altrimenti non ci sarà corrispondenza fra i dati scritti e quelli letti;

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Anche qui la prima cosa da fare è chiamare InitRead che abilita la lettura della memoria condivisa, quindi ogni volta che devi leggere i dati chiami Read, mentre per modificarli devi chiamare Write, passando come argomento un'istanza contenente i nuovi dati. Prima di chiudere l'applicazione devi sempre chiamare EndRead che dealloca la memoria non gestita e chiude l'handle del processo aperto.

Luca

aiedail92 Profilo | Expert

Ho ampliato il codice del post precedente, adesso c'è anche una funzione per modificare i dati oltre che leggerli. Nota che entrambe le applicazioni devono ottenere i dati dalla memoria condivisa prima di poterle utilizzare, quindi anche l'applicazione che li elabora deve prima ottenerli, e ciò potrebbe rallentare l'applicazione. Quello che puoi fare (e che ho fatto) per evitare di aggiornare dalla memoria ad ogni passaggio è di avvisare l'applicazione che elabora i dati di aggiornarsi solo quando un flag nella memoria condivisa è impostato.

Trovi tutto il codice nel post precedente che ho aggiornato.

Luca

beguroto Profilo | Junior Member

Ti ringrazio ancora una volta, ho letto il codice ed è davvero comprensibile e ben commentato.
Vorrei chiederti un' altro suggerimento. Nella struttura "struct SharedData" riportata nel tuo post:
struct SharedData
{
public int v1;
public bool v2;
public char v3;
public Point v4;
//Non puoi inserire delle variabili di tipo classe
//perchè sono dei tipi di riferimento, e non
//hanno senso nella memoria esterna
}
vado a definire le variabili che voglio monitorare, leggere e scrivere.

Vorrei sviluppare un software molto flessibile in cui per esempio definisco da esterno le variabili che col software voglio monitorare prima ovviamente di lanciare l' applicazione che va ad elaborarle eventualmente.
Riesco in qualche modo ad aggiornare la struttura SharedData da esterno aggingendo tramite text box per esempio una nuova variabile in SharedData senza dover per forza scrivere sul codice e ricompilarlo?
Vale a dire:
1) Realizzo un configuratore di variabili da monitorarizzare: un form dove definisco il nome della variabili, il tipo, ecc...
2)Salvo le variabili che ho inserito su un file (per esempio xxx.txt)
3)Vado a popolare la struttura in automatico con le variabili definite dal configuratore leggendo il file di testo
4)Dopo di che tutto continua come già riportato nel tuo esempio

Quindi:
tramite un form di configurazione posso un domani aggiungere un public int v5 senza entrare direttamente sul codice?
Riuscire ad avere un controllo del genere renderebbe il software molto flessibile per chi poi dovra utilizzarlo.
Come al solito , ogni suggerimento\consiglio è piu che ben accettato.

Ringrazio in anticipo per il supporto e la disponibiltà dimostrati.

Grazie,
Begs

aiedail92 Profilo | Expert

Ciao

In questo modo il tutto si complica, ma non è ancora impossibile

Inizio a spiegarti il meccanismo, se mi lasci un po' di tempo per scriverlo ti propongo anche un esempio

L'elemento da sfruttare per creare un'applicazione così "elastica" è senza dubbio la capacità di .Net di poter creare assembly "al volo". Vale a dire: quando avvii l'applicazione crei dinamicamente la struttura in base alle impostazioni necessarie (che vai a leggere dal file di testo)

Dico che diventa molto più complesso perchè devi compilare una classe scrivendo il codice "da codice", capisci che la gestione diventa più complessa. Appena ho finito con l'esempio ti faccio sapere.

Luca

aiedail92 Profilo | Expert

Ciao

Ho bisogno di un paio di informazioni in più:

1) L'applicazione che modifica le variabili sa a priori quali siano gli elementi da modificare e i loro tipi? Ossia, è la struttura che deve essere generata ad hoc per una determinata applicazione di elaborazione? Se così fosse il lavoro si semplificherebbe di parecchio;
2) Stesso discorso per l'applicazione che deve leggere i dati. Anche questo renderebbe il lavoro più semplice, anche se ha minore rilevanza.

Quello che intendo dire è: il codice dell'applicazione che deve elaborare i dati è basato su un insieme di dati che già conosce o li elabora senza sapere nè quanti, nè quali siano? O ancora più praticamente: chi scrive l'applicazione di elaborazione dei dati lo fa conoscendo a priori i dati che deve modificare?

Spero di essermi fatto capire, sapere queste cose mi renderebbe il lavoro molto più semplice.

Luca

beguroto Profilo | Junior Member

Buongiorno,
dunque l' applicazione che deve elaborare i dati non conosce a priori quali sono le variabili da esaminare.
Mi spiego meglio: creo il mio configuratore che da esterno mi permette di definire le variabili che voglio tenere sotto controllo: 3 interi, 4 booleani, ecc.... Una volta definite queste vaiabili vorrei fare in modo che lanciando la mia prima applicazione essa capisca quali variabili deve tenere sotto controllo acquisendole dall' esterno e\o elaborarle. Stessa cosa per l' applicazione 2.

La flessibilità che vorrei implementare sta nel fatto che se per qualunque motivo ho necessita di inserire il monitoraggio di un altra variabile, per esempio un quarto intero e un quinto booleano, allora mi piacerebbe che chiudendo l apllicazione 1 e 2 e aprendo il mio configuratore vado a defiire le nuove variabili cosi che poi, rilanciando l' applicazione 1 e 2, esse vadano ad aggiornarsi con le nuove variabili inserite.

Spero di esere stato abbastanza comprensibile :-)

Grazie per la disponibilità. Attendo con ansia tue news :-)


Begs

aiedail92 Profilo | Expert

Ok, a questo punto gli approci che puoi utilizzare sono diversi:

Potresti creare l'assembly in memoria per entrambe le applicazioni leggendo i parametri da un file di testo o dal registro; altrimenti potresti compilare una dll al volo ed appoggiarti ad essa solo per la definizione della struttura. Ancora meglio, sempre usando la dll, puoi compilarla dinamicamente includendo anche i metodi per leggere\scrivere le variabili nella memoria condivisa, e usare la dll come "centro comune" di tutto il lavoro. Quest'ultima possibilità ti consente di compilare una sola volta quando vuoi modificare la struttura, e di avere tutto il necessario a disposizione per qualsiasi applicazione voglia sfruttarlo.

L'unica cosa che ancora non mi è chiara è se vuoi prendere i dati dalla seriale e interpretarli senza che l'applicazione sappia come deve trattarli. O meglio, l'applicazione dovrebbe "autoistruirsi" leggendo lo stesso file di configurazione che poi dovrebbe usare la dll e anche l'applicazione che mostra i valori? E quindi se non devi ricompilare l'applicazione che legge i dati dalla seriale, hai bisogno di interpretare una "serie di byte" (dati letti) come una "struttura ordinata", giusto?

Questa è l'idea che mi sono fatto io, dimmi se è corretta:


600x340 57Kb


Luca

beguroto Profilo | Junior Member

Ciao,
ti ringrazio ancora una volta per il supporto che stai dandomi.

L' idea che hai avuto è fattibilissima ed è esattamente quello il giro dei dati.

Mi verrebbe però da pensare ad un sistema ancora più flessibile del tipo: mi creo il mio configuratore che ogni volta che viene aperto carica da file il corrente listato delle variabili definite. A questo punto devo poter inserire nel mio "database" di variabili o rimuoverle. Fatte queste modifiche al listato mi immagino di poter aggiornare il mio file salvandolo e successivamente tramite un "bottone" LOAD caricare il nuovo listato su un array della memoria condivisa che tutte le applicazioni potrebbero andare a leggere e scrivere.
E' fattibile secondo te realizzare una cosa del genere? Aggiornare un array in memoria affinchè contenga le variabili che ho definito ogni volta che clicco su load, per esempio!?!?!?
Mi verrebbe anche da pensare ad una struttura predefinita che possa contenere al massimo tot variabili per ogni tipo.Ma non la vedo molto efficace come approccio.

Trascuriamo momenteneamento la necessita di leggere da seriale.

Attendo con piacere tue news.

Grazie infinite,

Begs




aiedail92 Profilo | Expert

Quello che pensavo di fare io era una cosa del genere:

Applicazione di configurazione: definisce le variabili da salvare e l'ordine in cui salvarle (che è rilevante), in pratica definisce la struttura, e la compila in un'assembly (dll)
Applicazione 1: ha una serie di dati (un array di byte che potrebbero essere stati letti dalla seriale), converte quest'array nella struttura precedentemente compilata e salva i dati nella memoria condivisa (tramite una funzione apposita esposta dalla dll)
Applicazione 2: quando glielo chiedi, va a leggere la memoria condivisa, ottiene i dati letti sotto forma della struttura compilata (sempre mediante una funzione esposta dalla dll), e analizzando i tipi delle variabili mostra i risultati sotto forma di bool, int, double ecc...

Quello che farebbe l'applicazione 1 in pratica sarebbe questo:

450x600 93Kb


Luca

beguroto Profilo | Junior Member

Mi daresti una mano nella realizzazione della dll contenente le funzioni di letture e scrittura delle variabili come mi hai accennato nel post precedente?
Cosi facendo, se io mettessi una text box nell applciazione 2 posso poi andare a scrivere su una variabile che è condivisa in memoria?

Se hai qualcosa di pronto, del codice già scritto, me lo passeresti affinchè possa studiarlo un pò e capire meglio le varie chiamate che avvengono?

Ti ringrazio davvero molto.

Begs

aiedail92 Profilo | Expert

Le funzioni vengono compilate "al volo" assieme alla struttura, tutto all'interno della dll, dall'applicazione di configurazione. Sto scrivendo il codice di esempio, forse potrebbe volerci un pochino, spero tu riesca a pazientare ancora un attimo, e chiedo scusa per i ritardi

Il codice lo sto scrivendo con la versione 2008 di Visual Studio, se ne hai una precedente non riuscirai ad aprire la soluzione, quindi dovrai o scaricare una versione express oppure creare una nuova soluzione e aggiungere manualmente i file.

Ti dò ulteriori notizie appena ho finito, ciao!

Luca

aiedail92 Profilo | Expert

Ciao

Ho finito di scrivere il codice, lo trovi nell'allegato.

Il funzionamento è questo: per prima cosa compili il progetto ShredStructCompiler, che sarebbe l'applicazione che si occupa di compilare dinamicamente la struttura. Dopo aver compilato la struttura aggiungi un riferimento all'assembly compilato agli altri due progetti, poi puo compilare anche quelli.

Quando vuoi modificare la struttura ti basta ricompilarla usando l'applicazione apposita, e copiare la nuova dll nella cartella delle applicazioni sostituendo quella precedente. I progetti sono fatti per ottenere nomi delle variabili e tipi direttamente dalla dll, quindi aggiornando quella (in entrambe le applicazioni) tutta la gestione risulta aggiornata.

Scusa se ci ho messo così tanto tempo, ma fra verifiche e interrogazioni non si sta mai tranquilli...

Luca

beguroto Profilo | Junior Member

Ti ringrazio per la volontà e l' impegno nell' aiutarmi in questo progetto.
Appena posso, non prima di un paio di settimane, proverò a lavorarci su e non esiterò nel chiederti consigli.
Nel frattempo se ho qualche perplessità provvederò a contattarti nel forum.

Grazie mille

Begs

beguroto Profilo | Junior Member

Buonasera a tutti....
Ancora non riesco a provare il software che mi hai postato tempo fa.... Scusami ma sono preso da un problema urgentissimo conADO.NET...
Sto sviluppando un' applicazione che mi permetta di interagire con un database access.
In allegato trovate un esempio di applicazione che sto portando avanti.
Ho un problema:
1) Se provo a compilare il database e salvarlo non vengono generati problemi
2) Se torno sul database che ho creato e lo modifico mi da la seguente eccezione:
"Update richiede un UpdateCommand valido se l'insieme DataRow viene passato con righe modificate."
Come posso risolvere tale problema? Spero vivamete in un vostro aiuto come al solito :-)

3)Posso inoltre inserire direttamente sulla datagrid view dei valori che imposto da una label per esempio? Senza dover obbligatoriamente scrivere nella casella del data grid view? Affinchè poi clicando su save me li salva in automatico sul datagrid view e quindi sul database...

Attendo vostre notizie....
Grazie anticipatamente

tizter Profilo | Newbie


Ciao a tutti.
Sono nuovo su questo forum.
Devo sviluppare del codice utilizzando la shared memory ed ho letto tutta la discussione

Sto facendo delle prove con il codice allegato (778_SharedMemoryExample.zip), ma mi da un errore sul tipo SharedData (riga 53) mi potreste dare una mano.

Grazie.

aiedail92 Profilo | Expert

Ciao,

Se come beguroto hai l'esigenza di mantenere in costante aggiornamento delle variabili condivise e di leggerne il valore da più processi, puoi utilizzare questo progetto. L'errore che ti appare è dovuto al fatto che devi prima compilare l'assembly con la definizione delle variabili da monitorare e quindi includerlo nei due progetti per la lettura e la scrittura delle variabili condivise.

Se invece quello che devi fare è solo passare dei dati da un processo ad un altro, ad esempio una stringa, puoi seguire una strada molto più semplice, ossia utilizzare le (Named) Pipes di Windows.

Fammi sapere

Luca

tizter Profilo | Newbie


Mi devo interfacciare con un applicazione del cliente tramite shared memory, non sapendo come fare sto spulciando su internet per capire meglio.
Quindi ho preso il tuo codice è lo sto studiando.
In allegato c'è un esempio del cliente, ma è scritto in c++ e non ci capisco molto....

Questo codice è molto semplice da utilizzare (inserisci l'indirizzo e il dato da scrivere) e poi viene visualizzata tutta l'area di memoria...

Io vorrei (tramite una mia applicazione in c# 2008) leggere e scrivere la stessa area di memoria dell'applicativo demo del cliente.
Cosi quando scrivo per vedere se funziona tutto mi basta leggere tramite l'applicativo del cliente.

Mi potresti dare qualche dritta giusto per capire meglio e andare avanti da solo....

Grazie

aiedail92 Profilo | Expert

Ciao

L'esempio che hai allegato crea in pratica una classe di appoggio (che viene poi esportata in una dll) da usare per interfacciarsi con altre applicazioni. Hai bisogno di utilizzare quella dll oppure puoi creartene una tua da usare in altre applicazioni gestite?

Luca

beguroto Profilo | Junior Member

Ciao Aiedail92,
finalmento ho un pò di tempo per riprendere il progetto di cui ti parlavo tempo fa.
Ho proavto ad aprire il tuo progetto: 778_SharedMemoryExample.zip e compilarlo: ottengo gli errori che puoi vedere dall' immagine in allegato.
Puoi aiutarmi?
Grazie in anticipo come al solito :-)

Attendo tue notizie,

Begs

aiedail92 Profilo | Expert

Ciao

Gli errori che vedi sono dovuti al fatto che prima di poter compilare il codice del Reader e del Writer, devi compilare (usando il terzo progetto della soluzione) la struttura SharedData che contiene le informazioni condivise.

Comunque dato che non hai ancora iniziato a studiare il codice ti allego una versione aggiornata, molto più semplice e pulita.

Luca

beguroto Profilo | Junior Member

Ti ringrazio davvero molto per l' impegno e la disponibilità che ogni volti dimostri.

Devo chiederti però un' ulteriore aiuto: adesso ho lanciato il programma che hai postato in allegato: non da alcun problema.
Compare una finestra nera e il tutto rimane fermo.

Potresti darmi quache dritta sul codice che hai scritto e come implementare un esempio di comunicazione?

Ti ringrazio,

Begs

aiedail92 Profilo | Expert

Ciao

Il programma che rimane nero è quello che effettua l'elaborazione dei dati. L'ho fatto come programma Console perché è in costante elaborazione, se guardi nella classe Elaborator, c'è una funzione Elabora, che prende i dati correnti dalla memoria condivisa:

this.data = SharedData.FromIntPtr(sharedMemPtr);

Ed effettua una elaborazione di esempio:

data.var1++; data.var2 = (data.var2 * 2 + 1) % 10000000000;

Quindi li risalva nella memoria condivisa:

this.data.SaveToIntPtr(this.sharedMemPtr);

L'elaborazione viene fatta in continuazione, infatti nella Main c'è un

while (true) { elab.Elabora(); }

Per visualizzare i dati correnti e\o modificarli, devi invece compilare e far partire l'applicazione SharedReader, l'interfaccia di questa applicazione si adatta alla struttura che hai compilato, e quindi clickando su Carica ti scrive nelle TextBox i valori correnti della struttura nella memoria condivisa, mentre clickando su Modifica salva i valori nella memoria (e verranno subito modificati dal SharedWriter, che è costantemente in azione, come puoi verificare clickando subito su Carica)

Luca

beguroto Profilo | Junior Member

Ciao,
sto studiando il codice allegato nel tuo post precedente, ho qualche dubbio:

1)Ho inizialmente lanciato il progetto SharedStructCompiler, ho assegnato il nome della variabile, tipo di variabile (int), poi dal menu FILE, ho lanciato COMPILA: mi chiedevo, su percorso dll cosa devo riportare? Appena inserisco un percorso e lancio compila mi da errore

2)Una volta compilata la mia struttura, mi genera il file test: cosa contiene? dove è posizionata la dll di appoggio per le atre due applicazioni reader e writer?

3)Lanciando compila dallo SharedStructCompiler crea il file test: a questo punto eseguo in sequenza SharedWriter e SharedReader.
Cliccando su carica (SharedReader) noto che mi da dei valori che si aggiornano ogni volta che effettuo un refresh...Le variabili però sono sempre due: var1 e var2 e non le variabili he io ho definito dal form che ho avviato SharedStructCompiler in precedenza e compilato ... Dove sbaglio?

4)L' esempio ultimo che hai postato, è capace di editare la struttura di variabii attualmente caricata e mostrarla a video ed eventualmente modificarla?Mi spiego meglio, lanciando SharedStructCompiler è capace di editare l' ultima definizione di variabili effettuata ed eventualmente modificarla?

Il codice è davvero interessante, se hai un paio di minuti da "regalare" mi daresti qualche dritta in più per focalizzare le istruzioni principali?
Di molte istruzioni che hai usato non ne sapevo nemmeno l' esistenza :-(

Ti ringrazio come al solito per la disponibilità e l' impegno...

Grazie,
Begs.

P.S.: Buone feste a tutti !!!

aiedail92 Profilo | Expert

>1)Ho inizialmente lanciato il progetto SharedStructCompiler,
>ho assegnato il nome della variabile, tipo di variabile (int),
>poi dal menu FILE, ho lanciato COMPILA: mi chiedevo, su percorso
>dll cosa devo riportare? Appena inserisco un percorso e lancio
>compila mi da errore

In percorso dll devi mettere il percorso completo (incluso il some) dell'assembly dove viene compilata la dll. Ad esempio potresti mettere "C:\SharedData.dll" (senza virgolette)

A questo punto negli altri due progetti devi sostituire la dll con quella nuova che hai compilato. (se cambi il nome devi anche aggiornare i riferimenti e ricompilare il progetto)

>2)Una volta compilata la mia struttura, mi genera il file test:
>cosa contiene? dove è posizionata la dll di appoggio per le atre
>due applicazioni reader e writer?

Come detto sopra, la dll compilata si trova nel percorso che specifichi, quando la aggiorni devi anche aggiornare i riferimenti dei progetti.

>3)Lanciando compila dallo SharedStructCompiler crea il file
>test: a questo punto eseguo in sequenza SharedWriter e SharedReader.
>Cliccando su carica (SharedReader) noto che mi da dei valori
>che si aggiornano ogni volta che effettuo un refresh...Le variabili
>però sono sempre due: var1 e var2 e non le variabili he io ho
>definito dal form che ho avviato SharedStructCompiler in precedenza
>e compilato ... Dove sbaglio?

Questo perchè non hai aggiornato la dll e i riferimenti nel progetto. Dopo che lo farai probabilmente ti arriveranno degli errori di compilazione perchè avrai definito delle variabili diverse da var1 e var2, quindi dovrai modificare il codice che modifica le variabili (SharedWriter.Elaborator.Elabora)

>4)L' esempio ultimo che hai postato, è capace di editare la struttura
>di variabii attualmente caricata e mostrarla a video ed eventualmente
>modificarla?Mi spiego meglio, lanciando SharedStructCompiler
>è capace di editare l' ultima definizione di variabili effettuata
>ed eventualmente modificarla?

Questo non l'ho messo, ma l'implementazione non è molto complessa. Se ne hai bisogno posso aggiornare l'esempio.

>Il codice è davvero interessante, se hai un paio di minuti da
>"regalare" mi daresti qualche dritta in più per focalizzare le
>istruzioni principali?

Certamente, sono sempre a disposizione , se vuoi puoi contattarmi su msn, trovi l'indirizzo nel mio profilo.

>Ti ringrazio come al solito per la disponibilità e l' impegno...

È un piacere dare una mano

>P.S.: Buone feste a tutti !!!

Buone feste anche a te!!

Luca

beguroto Profilo | Junior Member

Davvero grazie,
proverò nel pomeriggio ad aggiornare la dll e ti farò sapere.
Se non ti porta via molto tempo, aggiorneresti il progetto con la possibilità di editare l' ultima struttura salvata e compilata che il software sta utilizzando? Cosi facendo sarà anche possibile modificare la struttaura che ha editato? Per esempio ridefinire una variabile oppure cancellarla?

Grazie ancora per l' aiuto che mi stai dando!!!

Provvederò a contattarti su msn.

Grazie,
Andrea

aiedail92 Profilo | Expert

Ciao

Ho aggiornato lo SharedStructCompiler con la funzionalità che ti serviva... Il progetto lo trovi allegato, per usarlo devi fare queste cose:

1) Compila SharedStructCompiler e esegui il programma, quindi compila la tua Dll
2) Aggiungi ai riferimenti degli altri due progetti di esempio la Dll che hai precedentemente compilato. Per farlo devi clickare col destro su Riferimenti e scegliere "Aggiungi riferimento", quindi selezionare Sfoglia e cercare la Dll. Nelle proprietà della Dll imposta "Copia localmente" su true.
3) Aggiorna il codice dell'elaboratore in modo da non avere errori di compilazione. Infatti quando compili una nuova struttura con variabili diverse dalla precedente, il codice dell'elaborazione non potrà più essere valido.
4) Compila i due progetti e avvia prima lo SharedWriter e quindi lo SharedReader. Lo SharedWriter è in continua elaborazione, quindi la console resta nera; invece con lo SharedReader puoi leggere i valori correntemente salvati nella memoria condivisa e anche modificarli.
5) Ogni volta che compili una nuova Dll sostituiscila nelle cartelle di compilazione degli altri due programmi, ed eventualmente ricompilali per verificare di non avere variabili non valide.
6) Detto questo, leggiti bene il codice, divertiti e buon anno!!!

Luca

beguroto Profilo | Junior Member

Grazie Luca,
provvederò a leggere il codice appena possibile.

Buon anno,
Andrea

kiaruska_86 Profilo | Newbie

Complimenti per il codice aiedail!
Mi chiedevo se mi potevi spiegare a cosa serve il file test che viene creato utilizzando SharedStructCompiler.exe.
Grazie
kia

momift Profilo | Newbie

Ottimo esempio davvero bravo!!!
Una domanda ma quando tento di inserire (per la compilazione della dll dei parametri condivisi) un tipo string mi da l'errore di tipo valore, non è possibile inserire campi di tipo string ???

Garzie

aiedail92 Profilo | Expert

Ciao, scusate se rispondo solo ora

Per kiaruska_86: lo SharedStructCompiler serve a creare dinamicamente una Dll da utilizzare poi con gli altri due programmi; in questa Dll è definita una struttura, SharedStruct, che rappresenta in pratica il formato dei dati che vengono salvati nell'area di memoria condivisa.

Per momift: purtroppo non è possibile inserire dati di tipo riferimento (in sostanza, classi) per la loro "caratteristica essenziale": il valore di una classe non è l'oggetto stesso, ma è solo un puntatore ad un oggetto, creato in memoria (chissà dove, il fw non ci concede di saperlo). Per questo motivo non è possibile inserire una String fra le variabili della struttura, perchè copiando il "collegamento" (il puntatore all'oggetto) nella memoria condivisa, andrebbe a puntare su memoria inesistente nel suo ambito. Spero di essere stato abbastanza chiaro , se vuoi maggiori delucidazioni basta che chiedi

Luca

kiaruska_86 Profilo | Newbie

Salve aiedail,
volevo delle delucidazioni ...
Se io volessi condividere una matrice di float ... come posso fare?
Una matrice è un array bidimensionale, quindi un reference type, (se sbaglio correggimi) quindi l'allocazione viene fatta sullo heap e non può essere condivisa...
In attesa di notizie
Grazie

--------------------------- 29 maggio -----------------------------------
Cercando su internet ho trovato due possibili soluzioni... può essere che ne esista una migliore ...
- scrivere una DLL in C++ dove è possibile stabilire a tempo di compilazione la dim dell'array [o almeno credo]
- Usare http://msdn.microsoft.com/it-it/library/ms172512.aspx

Mi piacerebbe sapere se vanno bene come soluzioni, e soprattutto riuscire a capire la differenza tra struttura gestita e non gestita...
Grazie mille

Adidas_DotNet Profilo | Newbie

ciao a tutti ho seguito questo post ed ho trovato interessantissimo il programma di aiedail92 davvero ber fatto e commentato egregiamente,scrivo qui perche non so come poter conttatare aiedail92 dato che sto utilizzando il suo codice per una cosa molto piu semplice, ma non riesco a venirne a capo se potere aiutarmi ve ne sono grato..voglio in pratica avere due programmi che interagiscono sulla memoria stessa memoria condivisa,il primo contiene un form con una textbox dove l'utente immette il valore della variabile e tramite un pulsante viene inviato scrivere sulla memoria condivisa la variabile variabile,il secondo programma deve leggere la stessa zona di memoria prelevare la variabile e immetterla in una textbox.spero sia chiaro cosa deve fare...
ora io ho prelevato il codice di aiedail92 e ho preso http://www.dotnethell.it/forum/ShowCode.aspx?MessageID=101993&Frag=1 da questo thread ho diviso il codice in due funzioni la initread e read nella parte da leggere mentre la initwrite=initread e write dall'altra...ma l'unica cosa che leggo e uno 0
di sugito allego copia del codice sperando che qulcuno possa aiutarmi:

Private Sub CTRL_LEGGI_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CTRL_LEGGI.Click
Dim Test As ReadElemDit
Test = New ReadElemDit
Test.InitRead()
Test.Read()
TXT_Attuale.Text = ReadElemDit.value.ToString
CTRL_STORICO.Items.Add(TXT_Attuale.Text)
Thread.Sleep(1000)
End Sub
Private Sub CTRL_SCRIVI_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CTRL_SCRIVI.Click
' Dim scrivi As WriteElemDit
Dim C As String
C = TXT_INSERIRE.Text
' scrivi = New WriteElemDit
'scrivi.InitSharedMem()
'scrivi.Scrivi(C)
End Sub
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5