2011-12-04 17 views
8

Pracuję nad osadzeniem mono w aplikacji, którą tworzę, i nie dostałem super daleko, ale jedną z rzeczy, których nie mogę znaleźć, jest jak powiedzieć mono, gdy używam obiektu i wykonuję obiekt.Embedded Mono: Przechowywanie odwołań do obiektów C# w C++

Chcę zachować odniesienie do obiektu C#, aby wywoływać metody, dopóki nie zakończy się okres jego równoległego obiektu w C++, w którym to momencie chcę powiedzieć mono, że obiekt C# jest bezpieczny do zebrania.

Jak to się robi?

+0

Znam ['gcroot'] (http://msdn.microsoft.com/en-us/library/481fa11f (VS.80) .aspx) dla implementacji Microsoft .NET, ale nie jestem pewien, czy to będzie istniało dla Mono. Wątpię, aby ten interfejs zarządzany na natywnie był przenośny. –

+0

Miałem ten sam problem i rozwiązałem go przez posiadanie statycznego pola po zarządzanej stronie, do której przypisałem obiekt, aby nigdy nie było gromadzone przez gc. –

Odpowiedz

3

Wygląda na to, że to, czego szukam, to mono_gchandle_new i przytrzymaj uchwyt, a nie obiekt MonoObject * i używaj mono_gchandle_get_target, gdy jest to potrzebne.

mono_gchandle_new pozwala przypiąć podczas tworzenia klamki, ale czy można przypiąć po fakcie?

+1

Nie można przypiąć po fakcie, ale można utworzyć nowe, przypięte gchandle. –

+0

Dobre połączenie. Dzięki. – Jeff

0

Jedna rzecz, o której należy pamiętać podczas korzystania z funkcji mono_gchandle_new(), z którą się spotkałem. Zachowa ona tylko obiekt C#, do którego odwołuje się w pamięci, ale jeśli ten obiekt przydzieli inne obiekty, które są nadal przedmiotem procedur czyszczenia pamięci. Fakt, że obiekt, do którego masz dostęp, może mieć uwolnione od ciebie obiekty podrzędne, przysporzył mi sporo kłopotów.

Aktualnie pracuję w systemie mono GC, aby sprawdzić, czy mogę go naprawić, aby traktował te obiekty jako obiekty root.

Jeśli masz za mało obiektów (< 4096), możesz użyć mono_gc_register_root() ... możemy mieć tysiące obiektów, więc nie jest to dobre dla naszych zastosowań.

AKTUALIZACJA: Tak więc nie miałem racji, połączyliśmy się z systemem alokacji obiektów mono i nie przejeliśmy poprawnie zmiennej "atomowej" na funkcje alokacji GC. "Atomowy" oznacza coś innego niż GC, nie ma nic wspólnego z równoczesnym dostępem, to znaczy, że pamięć jest przydzielana jako odniesienie do innych obiektów (atomowej = 0) lub nie (atomowa = 1).

+0

To jest ... dziwne. Wersja Microsoftu, 'clr :: gcroot', jest cienkim opakowaniem wokół' System :: GCHandle'. 'System :: GCHandle' zdecydowanie służy jako root i chroni wszystkie obiekty dostępne bezpośrednio lub pośrednio od niego. Jeśli to nie działa, może po prostu użyj wartości liczbowej z 'System :: GCHandle'? –

+0

Tak, to dziwne ... prawdopodobnie używamy mono w taki sposób, w jaki wcześniej nie był on używany. Owinął obiekt C# obiektem C++ i użyć naszego wewnętrznego systemu refleksyjnego, aby uzyskać dostęp do danych mono z C++. Myślę, że to mylące system GC w mono, więc weź mój komentarz powyżej z przymrużeniem oka. –

0

Użyj System::GCHandle::Alloc i zadzwoń pod numer , aby uzyskać token i zabezpieczyć obiekt przed pobraniem. Zadzwoń pod numer ToPointer() i zapisz jako void*.

Użyj System::GCHandle::FromIntPtr, gdy chcesz zmapować token do obiektu lub zwolnić go, aby ponownie mógł zostać odebrany.

Powiązane problemy