2009-06-09 14 views
5

Łączę się ze składnikiem ActiveX, który podaje adres pamięci i liczbę bajtów.Dostęp do adresu pamięci w C#

Jak napisać program w języku C#, który będzie uzyskiwał dostęp do bajtów rozpoczynających się od podanego adresu pamięci? Czy istnieje sposób, aby to zrobić natywnie, czy też będę musiał połączyć się z C++? Czy komponent ActiveX i mój program mają tę samą przestrzeń pamięci/adresową?

Odpowiedz

7

Sugeruję użycie IntPtr i Marshal.Copy. Oto kod, który pomoże Ci zacząć. memAddr to podany adres pamięci, a wartość bufSize to rozmiar.

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

nie wymaga użycia niebezpieczny kod, który wymaga do niebezpiecznej opcji/kompilatora i nie można zweryfikować przez CLR.

Jeśli potrzebujesz tablicy czegoś innego niż bajty, po prostu zmień drugą linię. Marshal.Copy ma kilka przeciążeń.

+0

Dzięki za próbkę kodu; właśnie to wykorzystałem. – chocojosh

2

Myślę, że szukasz typu IntPtr. Ten typ (jeśli jest używany w bloku unsafe) pozwoli ci użyć uchwytu pamięci ze składnika ActiveX.

10

Można użyć Marshal.Copy, aby skopiować dane z pamięci macierzystej do zarządzanej tablicy. W ten sposób możesz następnie użyć danych w zarządzanym kodzie bez użycia kodu unsafe.

+0

Jest to prawdopodobnie znacznie bardziej elegancki sposób niż używanie niebezpiecznego kodu. Mój program działa teraz z niebezpiecznym kodem; ale, wrócę do niego później, aby sprawdzić, czy mogę go zastąpić Marshal.Copy – chocojosh

1

C# można używać wskaźników. Po prostu użyj "niebezpiecznego" słowa kluczowego przed twoją klasą, blokiem, metodą lub zmienną składową (nie zmiennymi lokalnymi). Jeśli klasa jest oznaczona jako niebezpieczna, wszystkie zmienne składowe są również niebezpieczne.

unsafe class Foo 
{ 

} 

unsafe int FooMethod 
{ 

} 

Następnie można użyć wskaźników z * i & podobnie jak C

nie wiem o komponentów ActiveX w tej samej przestrzeni adresowej.

+0

Skończyło się na tym rozwiązaniu po opublikowaniu pytanie. _axetRecord1.SourceBufferMemoryPointer zapisuje lokalizację początku bufora pamięci. Następujący kod działa: [kod] krótki * memPtr; memPtr = (short *) _ axetRecord1.SourceBufferMemoryPointer; [/ code] – chocojosh

+0

Musisz przypiąć instancję, jeśli masz zamiar przekazać ją do natywnego kodu! –

Powiązane problemy