[ Nidza2010 @ 02.05.2012. 18:03 ] @
Da li moze neko da mi kaze kako uraditi late binding na COM? Znaci ne na Automation, tj objekat koji nema IDispatch interface. Ja sam napravio interfejs klase koju zelim da koristim, marshalling je ispravan, ali kada pokusam da castujem objekat koji sam dobio sa CreateInstance dobijam run-time gresku da nema podrske za IDispatch. Kako pristupiti metodama ako postoji samo IUnknown interfejs?

PS trazio sam po internetu, nisam nasao nista, pa ako nekoga mrzi da mi objasnjava bicu zahvalan i za link.

Hvala
[ mmix @ 02.05.2012. 18:25 ] @
Daj malo koda. Kako izmgleda ComImport klasa? Kako si je generisao (tlbimp?)

Btw, late binding je nesto drugo (kad pozivas elemente objekta preko IDispatch), late binding jer se bindujes na elemente u momentu poziva. Ono sto ti pretpostavljam hoces je da instanciras objekat, dobijes IUnknown i da iz njega uradis QueryInterface?
[ Nidza2010 @ 02.05.2012. 23:42 ] @
Nisam znao da je sve sto ide preko IDispatch-a late binding, mislio sam da je to sve sto u Run-time-u povezes na COM. Da Early Binding koristi isti metod na napravi proxy/stub?!
Pa nema nesto koda, sve se svelo na Type.GetTypeFromProgID, Activator.CreateInstance, Marshal.GetIUnknownForObject od instanciranog objekta i Marshal.QueryInterface za IUnknown. Interfejs koji sam rucno pravio je klasican (nema tlibimp, ali je marshalovan):
Code:
interface IServerList
    {
        int EnumClassesOfCategories([In] int cImplemented, [In, MarshalAs(UnmanagedType.LPArray)] Guid[] catidImpl, [In] int cRequired, [In] Guid[] catidReq, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnk);
        int GetClassDetails([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string ppszProgID, [MarshalAs(UnmanagedType.LPWStr)] out string ppszUserType);
        int CLSIDFromProgID([In, MarshalAs(UnmanagedType.LPWStr)] string szProgId, out Guid clsid);
    }

Na osnovu prethodnog posta, mislim da je mozda stvar u GUID-u interfejsa klase koju zelim, ali ne znam kako to da izvucem. Mozda je nebitno, ali zapravo hocu da se povezem sa DCOM, tako da iz Registry-a ne mogu da procitam ID.
[ mmix @ 03.05.2012. 07:57 ] @
Interface GUID (IID) je zapravo najvaznija stvar, perko njega QueryInterfejs vraca interface. I sam COM activator koristi CLSID (Class ID) a n ProgID za ucitavanje i instanciranje objekta, progID je samo programer firendly name iz dana VB6 za koje mora da postoji mapitanje u CLSID u registry-u.

Iskreno nisam bas isguran kako bi ovo mogao da koristis na jednostavan nacin, Marshal.QueryInterface je cisto interop fora (da ti nekome prosledis COM interface, ne da ga zoves iz c# koda) sto se vidi i iz povratnog tipa u koji smesta interface (IntPtr). Tebi treba RCW (Runtime Callable Wrapper) a da bi njega dobio treba ti minimum IDL file, a za njega ti opet treba GUID i objekta i interface-a.

Meni je veoma cudno da taj COM objekat nema svoj type lib, cak i da ne podrzava IDispatch kako je registrovan u DCOM ako nema typelib?

Na osnovu progID, lociraj u registriju koji DLL ga sadrzi (ako vec ne znas), i probaj da pozoves tlbimp na tom DLLu. Ako nema, moja preporuka ti ej da sam napravis repliku IDL fajla za taj objekat.