2012-05-06 10 views
5

Próbuję napisać małą bibliotekę, która będzie używać DirectShow. Ta biblioteka ma być używana przez aplikację .NET, więc pomyślałem, że najlepiej będzie napisać ją w C++/CLI.Jak mogę użyć "natywnego" wskaźnika w klasie odniesienia w C++/CLI?

mam problemy z tej linii Jednakże:

HRESULT hr = CoCreateInstance( CLSID_FilterGraph, 
            NULL, 
            CLSCTX_INPROC_SERVER, 
            IID_IGraphBuilder, 
            (void**)(&graphBuilder)); //error C2440: 

Gdzie graphBuilder jest zgodność:

public ref class VideoPlayer 
{ 
public: 
    VideoPlayer(); 
    void Load(String^ filename); 

    IGraphBuilder* graphBuilder; 

}; 

Jeśli jestem zrozumienia this page poprawnie, mogę wykorzystać */& jak zwykle do określenia „natywny” wskaźniki do niezarządzanej pamięci w mojej bibliotece C++/CLI; ^ służy do oznaczenia wskaźnika do zarządzanego obiektu. Jednak ten kod produkuje:

błędu C2440: 'typu cast': nie można przekonwertować z 'cli :: interior_ptr' do 'void **'

Błąd sugeruje, że graphBuilder jest uważana za a 'cli::interior_ptr<Type>'. To jest wskaźnik/uchwyt do zarządzanej pamięci, prawda? Ale jest to natywny wskaźnik. Nie próbuję przekazać wskaźnika do metody oczekującej uchwytu lub odwrotnie - po prostu chcę przechowywać ją w mojej zarządzanej klasie). Jeśli tak, jak mogę powiedzieć, że jest to "tradycyjny" wskaźnik?

(This question jest podobna, ale odpowiedź, aby użyć pin_ptr, nie widzę pomaga mi, ponieważ nie może być członkiem mojej klasy)

Odpowiedz

9

Komunikat o błędzie jest nieco tajemniczy, ale kompilator próbując przypomnieć, że nie można przekazać wskaźnika do elementu zarządzanej klasy do niezarządzanego kodu. To nie może działać według projektu, katastrofa uderza, gdy wywoływacz śmieci kopie podczas wykonywania funkcji i przenosi zarządzany obiekt. Unieważnienie wskaźnika do elementu w procesie i spowodowanie, że natywny kod rozpyla bajty na stertę Gc pod niewłaściwym adresem.

Obejście problemu jest proste, wystarczy zadeklarować zmienną lokalną i zamiast tego podać wskaźnik. Zmiennych na stosie nie można przenieść. W ten sposób:

void init() { 
    IGraphBuilder* builder; // Local variable, okay to pass its address 
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_IGraphBuilder, 
     (void**)(&builder)); 
    if (SUCCEEDED(hr)) { 
     graphBuilder = builder; 
     // etc... 
    } 
} 
+0

Sam wskaźnik może się poruszać podczas ustawiania - zupełnie to przegapiłem! Dziękuję Hans! – sebf

+0

Tak więc, aby było jasne, mówisz, że nie możesz zachować niezarządzanego wskaźnika jako nawet wewnętrznego członka zarządzanej klasy? Próbuję obrócić głowę, jak mam łączyć się między typami zarządzanymi i niezarządzanymi w spójny sposób, jeśli to prawda. –

+0

Nie, w porządku. OP stworzył wskaźnik do elementu obiektu & graphBuilder. –

Powiązane problemy