Re: hosting the runtime



Anyway, I finally write a tiny, almost correct loader (well can't be sure,
it doesn't link :( yet..), I attached it for academic purpose (hehe, doesn't
that souds good when said like that?)

I'll try to compile with VS next, I might have more success than with gcc?
(I can't be sure yet, now I'm uninstalling problem, I think I get messed up
by beta 1/ beta 2)

Anyway, using COM doesn't seems so hard, there is just the magic about find
the right GUID_xxxx and knowing you have this std Release method...

And yup, Aussie is definitely a good place. I'm french originally (although
Australia born ;)..
And for waht I read on the news I hesitate between America is great or
America is not such a good place to have a good life in....


"Sahil Malik [MVP]" <contactmethrumyblog@xxxxxxxxxx> wrote in message
news:%23oQw%23ledFHA.3012@xxxxxxxxxxxxxxxxxxxxxxx
> Holy cow Richard, I admire the effort you put in this answer. And yes,
> Dale
> Rogerson was the author I was referring to. Thats an awesome book IMO.
> BTW,
> I've read your book on ATL+COM. Another good book.
>
> - Sahil Malik [MVP]
> Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
> ----------------------------------------------------------------------------
>
>
> "Richard Grimes [MVP]" <read my sig> wrote in message
> news:%23IQb8vddFHA.1448@xxxxxxxxxxxxxxxxxxxxxxx
>> Sahil Malik [MVP] wrote:
>>> So a COM component has a lot to be told about - more than I can
>>> possibly type here. I'd recommend Inside COM by Don Box.
>>
>> Hmmm, Inside COM was written by Dale Rogerson, and IMO not particularly
>> relevant here. Don's book is Essential COM. ;-)
>>
>> First, its worth pointing out that a COM interface is very much like a
>> C++
>> v-table. Imagine COM marshalling as being a mechanism to transport a
>> v-table from one COM object in one memory space and make it available in
>> another memory space.
>>
>> COM itself is essentially a mechanism to manage DLLs (we'll ignore 'local
>> servers'). Imagine that you want to create an instance of a class class
>> and you know the name of the DLL. The problem in Win32 is that you first
>> have to locate the DLL and load it - this is the DLL hell problem,
>> because
>> LoadLibrary will look in various places for the DLL and may pick up a
>> different version of the DLL or even a totally different DLL that has the
>> same name. COM manages this through values in the registry, when you
>> install a COM server the classes it contains will be registered in the
>> registry and these entries will contain the full path to the DLL. ***It
>> is
>> vitally important that the location of a COM server DLL does not
>> change***. Each class has a unique name called a GUID (a 128 bit integer)
>> and so whenever you create an object you create it via its GUID.
>> Languages
>> do have mappings to human readable names, but it is important to realise
>> that the real name of a class is the GUID. COM provides APIs that when
>> given a GUID will locate and load the DLL containing the class.
>>
>> Next you need to create an instance of the class, which means finding
>> some
>> code that will create it for you. Since you don't want a memory leak, you
>> also have to have a mechanism to remove the instance. COM objects are
>> usually created by class factory objects, a class factory is intimately
>> intwined with an object because the class factory calls new with whatever
>> memory manager it wants to use, and hence when the object is destroyed it
>> must call the appropriate delete.
>>
>> So you need to get access to a class factory object in the DLL. However,
>> DLLs can only export C functions. So all COM server DLLs have to export a
>> function called DllGetClassObject. In effect you pass the name (GUID) of
>> a
>> class to this function and it will return the class factory interface of
>> the class factory object (remember an interface is just a v-table
>> pointer,
>> so all you get back is a pointer to a table of pointers). You can then
>> call the IClassFactory::CreateInstance to create an instance of the
>> class.
>> Note that *all* access to COM objects are via interfaces so you need to
>> provide an identifier about what interface you want to have on the new
>> object.
>>
>> All COM objects must implement IUnknown which has three methods:
>> QueryInterface allows you to ask for a specific interface, it's
>> equivalent
>> to the C++ dynamic_cast<>. Note that there is no mechanism to get a list
>> of the interfaces on an object, instead, you have to call QueryInterface
>> for the interfaces that you want to use. The other two methods are AddRef
>> and Release. These maintain a reference count (usually on the object) and
>> when you make a copy of an interface pointer you have to call AddRef,
>> when
>> you no longer need the pointer you have to call Release. Once the
>> reference count falls to zero the object can delete itself. (What this
>> means is up to the object, but it usually means calling the delete on its
>> this pointer that corresponds to the new that the class factory called.)
>>
>> The beauty of interfaces is that it allows polymorphism, because a method
>> that takes an interface pointer does not care what object the pointer
>> points to, it just cares about the behaviour of the interface.
>>
>>> Non straightforward way - do what CoCreateInstance does -
>>
>> You pass the class's GUID and the indentifier (another GUID) of the
>> interface you want on the object to CCI, which will locate the DLL, call
>> the class factory, create the object and then query for the specified
>> interface.
>>
>>>> on the other hand I never used COM interface, I have no idea on how
>>>> they work....
>>>> care writing me a veyr simple C:main() which load an exe?
>>
>> When you create a COM interface you write the interface in IDL and
>> compile
>> it with MIDL. MIDL will create a header file with a C++ and a C mapping
>> for the interface. The platform SDK contains MIDL generated header files
>> created for the standard interfaces. For example, here's IUnknown C
>> mapping from unknwn.h:
>>
>> typedef struct IUnknownVtbl
>> {
>> BEGIN_INTERFACE
>>
>> HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
>> IUnknown * This,
>> /* [in] */ REFIID riid,
>> /* [iid_is][out] */ void **ppvObject);
>>
>> ULONG ( STDMETHODCALLTYPE *AddRef )(
>> IUnknown * This);
>>
>> ULONG ( STDMETHODCALLTYPE *Release )(
>> IUnknown * This);
>>
>> END_INTERFACE
>> } IUnknownVtbl;
>>
>> interface IUnknown
>> {
>> CONST_VTBL struct IUnknownVtbl *lpVtbl;
>> };
>>
>> So when you call CoCreateInstance in C you will get back an IUnknown* to
>> call a method you need to derefernce it to get the lpVtbl, and then
>> dereference that to get to the function pointer that you want to call. In
>> C++ the interface is treated as a C++ class v-table (the language mapping
>> does this) so you only need to dereference it once. Also, the first,
>> implicit parameter of a v-table method is a this pointer. The C++ mapping
>> masks this, but in C you have to pass it explicitly.
>>
>> // C code
>> IUnknown* pUnk = NULL;
>> HRESULT hr;
>>
>> CoInitialize(); // must initialize COM, this creates a single threaded
>> apartment
>> hr = CoCreateInstance(&CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER,
>> &IID_IUnknown, &pUnk);
>> if (SUCCEEDED(hr)) // always check return values
>> {
>> // use the interface here...
>>
>> // finished with the interface so call Release
>> pUnk->lpVtbl->Release(pUnk);
>> // in C++ this would be pUnk->Release();
>> }
>> CoUninitialize(); // must uninitialise COM
>>
>> As you can see it is much easier in C++ so usually people don't bother
>> with C. The only book that I know off hand that shows how to program COM
>> in C is Brockschmidt's Inside OLE. However, I doubt if this is still in
>> print. Anyway if you are a proficient C programmer it should not be too
>> difficult to write C to access COM objects using the headers created by
>> MIDL.
>>
>> Richard
>> --
>> www.richardgrimes.com
>> my email evpuneqt@xxxxxxxx is encrypted with ROT13 (www.rot13.org)
>>
>>
>
>


begin 666 simple_loader.c
M#0HC:6YC;'5D92 \8F%S971Y<',N:#X-"B-I;F-L=61E(#QW:6YD;W=S+F@^
M#0HO+RTM(&9R;VT@35,G(%-$2R!2<&-.9'(N: T*(VEF(%]-4T-?5D52(#X]
M(#$Q,# -"B-D969I;F4@15A415).7T=5240H:71F+&PQ+',Q+',R+&,Q+&,R
M+&,S+&,T+&,U+&,V+&,W+&,X*2 @7 T*("!%6%1%4DY?0R!C;VYS="!)240@
M1$5#3%-014-?4T5,14-404Y9(&ET9B ]('ML,2QS,2QS,BQ[8S$L8S(L8S,L
M8S0L8S4L8S8L8S<L8SA]?0T*(V5L<V4-"B-D969I;F4@15A415).7T=5240H
M:71F+&PQ+',Q+',R+&,Q+&,R+&,S+&,T+&,U+&,V+&,W+&,X*2!%6%1%4DY?
M0R!C;VYS="!)240@:71F#0HC96YD:68-"@T*(VEN8VQU9&4@/&]L93(N:#X-
M"B-I;F-L=61E(#QM<V-O<F5E+F@^#0H-"B\O(&=C8R M;R!S;&]A9&5R+F5X
M92!S:6UP;&5?;&]A9&5R+F,@+4DB0SHO4')O9W)A;2!&:6QE<R]-:6-R;W-O
M9G0N3D54+U-$2R]V,BXP+VEN8VQU9&4B("U,(F,Z+W=I;F1O=W,O<WES=&5M
M,S(B("UL:V5R;F5L,S(@+6QM<V-O<F5E#0H-"G-T871I8R!V;VED(%-H;W=%
M<G)O<BA(4D5354Q4(&5R<BD-"GL-"@E,4%135%(@;7-G.PT*"49O<FUA=$UE
M<W-A9V4H( T*"0E&3U)-051?34534T%'15]!3$Q/0T%415]"549&15(@?"!&
M3U)-051?34534T%'15]&4D]-7U-94U1%32P@#0H)"4Y53$PL#0H)"65R<BP-
M"@D)34%+14Q!3D=)1"A,04Y'7TY%551204PL(%-50DQ!3D=?1$5&055,5"DL
M#0H)"2A,4%135%(I("9M<V<L( T*"0DP+" -"@D)3E5,3" I.PT*"0D-"@D)
M<')I;G1F*"(E<UQN(BP@;7-G*3L-"@D)3&]C86Q&<F5E*&US9RD[#0I]#0IS
M=&%T:6,@5T-(05(@8G5F6S(U-ET[#0IS=&%T:6,@5T-(05(J($UA:V574W1R
M:6YG*&-H87(J(&YA<G)O=RD-"GL-"@E70TA!4BH@=&UP(#T@xxxxxxx*"7=H
M:6QE*"IT;7 @/2 J;F%R<F]W*0T*"7L-"@D)=&UP("LK.PT*"0EN87)R;W<@
M*RL[#0H)?0T*"7)E='5R;B!B=68[#0I]#0IM86EN*&EN="!A<F=C+"!C:&%R
M("HJ87)G;"D-"GL-"@E)0TQ24G5N=&EM94AO<W0@*B!R=6YT:6UE.PT*"4A2
M15-53%0@:'([#0H)#0H):'(@/2!#;W)":6YD5&]2=6YT:6UE17@H3E5,3"P@
M3E5,3"P@,"P@0TQ3241?0TQ24G5N=&EM94AO<W0L($E)1%])0TQ24G5N=&EM
M94AO<W0L("A,4%9/240J*2 F<G5N=&EM92D[#0H):68H1D%)3$5$*"!H<B I
M*0T*"7L-"@D)<')I;G1F*")F86EL960@=&\@;&]A9"!R=6YT:6UE(&)E8V%U
M<V4Z7&Y<="(I.PT*"0E3:&]W17)R;W(H:'(I.PT*"0ER971U<FX@,3L-"@E]
M#0H)"0T*"6EN="!I.PT*"69O<BAI/3$[(&D\87)G8SL@:2LK*0T*"7L-"@D)
M:6YT(')E=&-O9&4[#0H)"6AR(#T@<G5N=&EM92T^;'!6=&)L+3Y%>&5C=71E
M07!P;&EC871I;VXH<G5N=&EM92P@36%K95=3=')I;F<H87)G;%MI72DL(# L
M($Y53$PL(# L($Y53$PL("9R971C;V1E*3L-"@D)#0H)"6EF*$9!24Q%1"AH
M<BDI"7L-"@D)"7!R:6YT9B@B)7,@9F%I;&5D(&)E8V%U<V4Z7&Y<="(L(&%R
M9VQ;:5TI.PT*"0D)4VAO=T5R<F]R*&AR*3L-"@D)?0T*"0EE;'-E('L-"@D)
M"7!R:6YT9B@B)7,@97AI=&5D('=I=&@@8V]D93H@)61<;B(L(&%R9VQ;:5TL
H(')E=&-O9&4I.PT*"0E]#0H)?0T*"0D-"@ER971U<FX@,#L-"GT-"@``
`
end

.



Relevant Pages

  • Re: hosting the runtime
    ... its worth pointing out that a COM interface is very much like a ... class and you know the name of the DLL. ... objects are usually created by class factory objects, ... v-table pointer, so all you get back is a pointer to a table of ...
    (microsoft.public.dotnet.framework)
  • Re: Passing pointers using a VARIANT
    ... You don't pass classes in COM - you pass interface pointers. ... Why do you believe it needs to be a COM DLL? ... the only way I can get that to work is if I cast the pointer ... What's the threading model of the component? ...
    (microsoft.public.vc.atl)
  • Re: hosting the runtime
    ... its worth pointing out that a COM interface is very much like a C++ ... > and you know the name of the DLL. ... > usually created by class factory objects, ... > so all you get back is a pointer to a table of pointers). ...
    (microsoft.public.dotnet.framework)
  • Re: Why we must use class factory to create some objects in COM?
    ... A dll can expose more than one component.Do u agree with this?If so, ... Instead of calling CoCreateInstancewhich just gives only one interface ... pointer of a component u can use ... You say it can create any number of components using class factory, ...
    (microsoft.public.vc.mfc)
  • Re: Properties Shared Amongst Objects
    ... The host can query my application for certain ... In that context one usually strives to provide a subsystem interface that reflects the invariants of the DLL subject matter. ... A some point the conversion may become so complex that one wants to deal with it explicitly within the DLL subject matter. ...
    (comp.object)