2009-06-09 6 views
5

Sto interagendo con un componente ActiveX che mi fornisce un indirizzo di memoria e il numero di byte.Indirizzo memoria di accesso in C#

Come posso scrivere un programma C# che acceda ai byte a partire da un dato indirizzo di memoria? C'è un modo per farlo in modo nativo, o dovrò interfacciare con C++? Il componente ActiveX e il mio programma condividono lo stesso spazio di memoria/indirizzo?

risposta

7

Consiglio vivamente di utilizzare un IntPtr e Marshal.Copy. Ecco un codice per iniziare. memAddr è l'indirizzo di memoria che ti viene dato e bufSize è la dimensione.

IntPtr bufPtr = new IntPtr(memAddr); 
byte[] data = new byte[bufSize]; 
Marshal.Copy(bufPtr, data, 0, bufSize); 

Questo non richiede di utilizzare codice non sicuro che richiede l'l'opzione del compilatore/pericoloso e non è verificabile dal CLR.

Se è necessario un array di qualcosa di diverso dai byte, è sufficiente modificare la seconda riga. Marshal.Copy ha un sacco di sovraccarichi.

+0

Grazie per l'esempio del codice; questo è quello che ho finito per usare. – chocojosh

2

Penso che stiate cercando il tipo IntPtr. Questo tipo (se utilizzato all'interno di un blocco unsafe) consente di utilizzare l'handle di memoria dal componente ActiveX.

10

È possibile utilizzare Marshal.Copy per copiare i dati dalla memoria nativa in un array gestito. In questo modo è quindi possibile utilizzare i dati nel codice gestito senza utilizzare il codice unsafe.

+0

Questo è probabilmente un modo molto più elegante rispetto all'utilizzo di codice non sicuro. Il mio programma ora funziona con codice non sicuro; ma, lo rivisiterò più avanti per vedere se posso sostituirlo con Marshal.Copy – chocojosh

1

C# può utilizzare i puntatori. Basta usare la parola chiave "non sicura" davanti alla classe, al blocco, al metodo o alla variabile membro (non alle variabili locali). Se una classe è contrassegnata come non sicura, tutte le variabili membro non sono sicure.

unsafe class Foo 
{ 

} 

unsafe int FooMethod 
{ 

} 

Quindi è possibile utilizzare i puntatori con * e & proprio come C.

Non so su componenti ActiveX nello stesso spazio di indirizzi.

+0

Ho finito per usare questa soluzione dopo aver postato la domanda. _axetRecord1.SourceBufferMemoryPointer memorizza la posizione dell'inizio del buffer di memoria. Il seguente codice funziona: [codice] breve * memPtr; memPtr = (breve *) _ axetRecord1.SourceBufferMemoryPointer; [/ code] – chocojosh

+0

Devi pin l'istanza se hai intenzione di passarlo al codice nativo però! –