From a COM Service EXE gets started - c++

I'm trying to program my first COM Service EXE. And I'm can't to find some informations in the Net.
A Service EXE starts executing from its Run() method, do I need to implement my main functions in it to get my service works or do I need to implement a specific function that is related to it?
Thank you so much !!

You have not stated that you are using C++ and ATL, but it can be guessed from the tags given to the question.
If your COM objects do not need any global initialization, you do not have to modify the provided Run() function or anything similar. It works like this: If the service is not running, and some program requires a COM object from your service be created, the COM/DCOM infrastructure first starts the service. Alternatively, you can pre-start the service using any standard means (e.g. manually, or set its startup type to Automatic). Once the service is running, the COM objects are created within the service.
So, without a need for extra global initialization, you simply implement your COM objects as in any local server or in-process server. If they need any instance initialization, you will put it into the constructor of the COM object, or to its FinalConstruct method (this method gets called after the constructor, so you have take advantage of the fact that the object already exists, AND you can also fail it if needed, as FinalConstruct returns an HRESULT).
If you need a global (service-wide) initialization code, then you can put it into several places, each at different stage of the service construction. One of such places would be the Run() method, yes.

Related

What is proxy and stub in web-services?

As per definition from https://channel9.msdn.com/Forums/TechOff/203516-Whats-a-proxy-stub
Proxy is the piece of code that doesn't perform any functions of its
own, but instead is responsible for calling the real code.
But I am not clear about stub,
What is stub, and what it does?
What is the difference between two?
Assuming you're talking RPC[1] systems in web services( SOAP[2], REST[3] etc)
What is stub?
A stub for a remote object acts as a client's proxy (local representative) for the remote object.
what it does?
It is responsible for carrying out the method call on the remote object which is invoked by a caller to a method.

Will COM marshalling be (ever) neccessary for an object with ThreadingModel Both?

This is triggered by another question.
Specifically, I have a in process COM class, that is defined in the CLSID registry as having a ThreadingModel of Both.
Our process activates this object through CoCreateInstance (not CoCreateInstanceEx, if that even matters for an in-proc dll server)
Given a threading model of Bothand given th rules listed in the docs:
Threading model of server | Apartment server is run in
------------------------------------------------------
Both | Same apartment as client
and given what Hans writes in the other answer:
... Marshaling occurs when the client call needs to be made on a
different thread. ... can happen when the ThreadingModel specified in
the comClass element demands it. In other words, when the COM object
was created on one thread but is called on another and the server is
not thread-safe.
my tentative conclusion would be that such an object will never need implicit marshalling of calls to its interfaces, since the object will always live in the same apartment as its client.
Is that correct, even if the client process is running as STA?
Yes, there may be marshaling.
If the client of your COM class is running in an STA and you attempt to invoke your class from another apartment, it will have to marshal to the apartment that it was created in.
The COM terminology can be really confusing. When you refer to a 'client' in this case, you're really referring to a thread, not the entire application (as it would imply).
Both just means that the threading model of the server conforms to the client that instantiates it. That is, when you instantiate your class, it takes on the threading model of the thread it was created on. Since you're instantiating the server in an STA, your server will use STA, meaning it can only be invoked on the thread that created it; if another thread tries to invoke it, it will marshal to the thread it was created on.
I can't help myself posting this, although it is not a direct answer to the question.
There's a brilliant MSKB article from the golden ages of COM: INFO: Descriptions and Workings of OLE Threading Models. Still there, and has all the relevant info. The point is, you should not worry about whether there is marshaling or not, if you follow the rules. Just register your object as ThreadingModel=Both, aggregate the Free-Threaded Marshaler with CoCreateFreeThreadedMarshaler, and be done. COM will do the marshaling if needed, in the best possible way. Depending on the client's apartment model, the client code may receive the direct pointer to your interface, if it follows the rules too.
Any "alien" interface that you may receive when a method of your interface gets called, will be valid in the scope of the call, because you stay on the same thread. If you don't need to store it, that's all that matters.
If however you do need to cache the "alien" interface, the right way of doing this would be to store it using CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream:
To store it:
Enter critical section;
call CoMarshalInterThreadInterfaceInStream and store the IStream pointer in a member field;
Leave critical section;
To retrieve it
Enter critical section;
call CoGetInterfaceAndReleaseStream to retrieve the interface
call CoMarshalInterThreadInterfaceInStream and store it again as IStream for any future use
Leave critical section;
Use the interface in the scope of the current call
To release it:
When you no longer need keeping it, just release the stored IStream (inside the critical section).
If the "alien" object is free-threaded too, and the things are happening inside the same process, you will likely be dealing with a direct interface pointer after CoGetInterfaceAndReleaseStream. However, you should not make any assumptions, and you really don't need to know if the object your dealing with is the original object or a COM marshaller proxy.
This can be slightly optimized by using CoMarshalInterface w/ MSHLFLAGS_TABLESTRONG / CoUnmarshalInterface / IStream::Seek(0, 0) / CoReleaseMarshalData instead of CoGetInterfaceAndReleaseStream/CoGetInterfaceAndReleaseStream, to unmarshal the same interface as many times as needed without releasing the stream.
More complex (and possibly more efficient) caching scenarios are possible, involving Thread Local Storage. However, I believe that would be an overkill. I did not do any timing, but I think the overhead of CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStreamis really low.
That said, if you need to maintain a state that stores any resources or objects which may require thread affinity, other than aforementioned COM interfaces, you should not mark your object as ThreadingModel=Both or aggregate the FTM.
Yes, marshalling is still possible. A couple of examples:
the object is instantiated from an MTA thread and so placed into an MTA apartment and then its pointer is passed into any STA thread and that STA thread calls methods of the object. In this case an STA thread can only access the object via marshalling.
the object is instantiated from an STA thread and so placed into an STA apartment belonging to that thread and then its pointer is passed into another STA thread or an MTA thread. In both cases those threads can only access the object via marshalling.
In fact you can expect no marshalling only in the following two cases:
the object is instantiated from an MTA thread and then only accessed by MTA threads - both the one that instantiated the object and all other MTA threads of the same process.
the object is instantiated from an STA thread and then only accessed by that very thread
and in all other cases marshalling will kick in.
ThreadingModel = Both simply means that the COM server author can give a guarantee that his code is thread-safe but cannot give the same guarantee that other code he didn't write will be called in a thread-safe way. The most common case of getting such foreign code to execute is through callbacks, connection points being the most common example (usually called "events" in client runtimes).
So if the server instance was created in an STA then the client programmer is going to expect the events to run on that same thread. Even if a server method that fires such an event was called from another thread. That requires that call to be marshaled.

Why calling GC.Collect is speeding things up

We have a C++ library (No MFC, No ATL) that provides some core functionality to our .NET application. The C++ DLL is used by SWIG to generate a C# assembly that can be used to access its classes/methods using PInvoke. This C# assembly is used in our .NET application to use the functionality inside C++ DLL.
The problem is related to memory leaks. In our .NET application, I have a loop in my .NET code that creates thousands of instances of a particular class from the C++ DLL. The loop keeps slowing down as it creates instances but if I call GC.Collect() inside the loop (which I know is not recommended), the processing becomes faster. Why is this? Calling Dispose() on the types does not have any affect on the speed. I was expecting a decrease in program speed on using GC.Collect() but it's just the opposite.
Each class that SWIG generates has a ~destructor which calls Dispose(). Every Dispose method has a lock(this) around the statements that make calls to dispose unmanaged memory. Finally it calls GC.SuppressFinalize. We also see AccessViolationException sporadically in Release builds. Any help will be appreciated.
Some types of object can clean up after themselves (via Finalize) if they are abandoned without being disposed, but can be costly to keep around until the finalizer gets around to them; one example within the Framework is the enumerator returned by Microsoft.VisualBasic.Collection.GetEnumerator(). Each call to GetEnumerator() will attach an object wrapped by the new enumerator object to various private update events managed by the collection' when the enumerator is Disposed, it will unsubscribe its events. If GetEnumerator() is called many times (e.g. many thousands or millions) without the enumerators being disposed and without an intervening garbage collection, the collection will get slower and slower (hundreds or thousands of times slower than normal) as the event subscription list keeps growing. Once a garbage-collection occurs, however, any abandoned enumerators' Finalize methods will clean up their subscriptions, and things will start working decently again.
I know you've said that you're calling Dispose, but I have a suspicion that something is creating an IDisposable object instance and not calling Dispose on it. If IDisposable class Foo creates and owns an instance of IDisposable class Bar, but Foo doesn't Dispose that instance within its own Dispose implementation, calling Dispose on an instance of Foo won't clean up the Bar. Once the instance of Foo is abandoned, whether or not it has been Disposed, its Bar will end up being abandoned without disposal.
Do you calling GC.SupressFinalize in your Dispose method? Anyway, there is nice MSDN article that explains, how to write GC friendly code - garbage collection basics and performance hints. Maybe it will be useful.

C++ setTimout function?

What's the cheapest way for a JavaScript like setTimeout-function in C++?
I would need this:
5000 miliseconds from now, start function xy (no parameters, no return value).
The reason for this is I need to initialize COM for text to speech, but when I do it on dll attach, it crashes.
It works fine however if I do not call CoInitialize from dllmain.
I just need to call CoInitialize and CoCreateInstance, and then use the instance in other functions. I can catch the uninitialized instance by checking for NULL, but I need to initialize COM - without crashing.
Calling CoInitialize() from DllMain() is a bad thing to do; there are LOTS of restrictions on what you can do from DllMain(); see here: http://blogs.msdn.com/larryosterman/archive/2004/04/23/118979.aspx
Even if it DID work reliably then initialising COM from within DllMain() isn't an especially nice thing to do as COM is initialised per thread and you don't know what the application itself wants to do with regards to COM apartments for the thread that you want to initialise COM for... This means that you might initialise COM in one way and then the application might need to initialise it in another way and might fail because of what your DLL had done...
You COULD spin up a thread in DllMain() as long as you are careful (see here http://blogs.msdn.com/oldnewthing/archive/2007/09/04/4731478.aspx) and then initialise COM on that thread and do all your COM related work on that thread. You would need to marshal whatever data you need to use COM with from whatever thread you're called on to your own COM thread and make the COM call from there...
And then there's the question of whether the instance of the COM object that you create (could you reliably do what you want to do) would be usable from the thread that was calling into your DLL to make the call... You do understand how you'd have to marshal the interface pointer if required, etc?
Alternatively you should expose YOUR functionality via COM and then have the application load your DLL as a COM DLL and everything will work just fine. You can specify the apartment type that you need and the app is responsible for setting things up for you correctly.
So, in summary, you don't need the answer to your question.
When it is OK to stop the execution for 5 seconds entirely, you can use the Winapi Sleep function. Beware that the documentation of Sleep minds some possible problems with CoInitialize and Messages.

CoCreateInstance returning E_NOINTERFACE even though interface is found

I have a COM class CMyCOMServer implementing IMyInterface in one application, both with correct GUIDs. CMyCOMServer::QueryInterface will return S_OK (and cast itself to the right type) if IUnknown or IMyInterface is requested, otherwise it returns E_NOINTERFACE.
In another app on the same PC, I call:
HRESULT hr = ::CoCreateInstance(__uuidof(CMyCOMServer), 0, CLSCTX_SERVER,
__uuidof(IMyInterface ),(void **)&pInterface);
It returns E_NOINTERFACE. So I assumed I was doing something wrong and added a breakpoint on CMyCOMServer::QueryInterface. I found that when CoCreateInstance is called, QueryInterface is triggered several times for different interfaces:
First, IUnknown is requested - no problem
Then, several interfaces like IMarshall etc are requested... these are not supported so E_NOINTERFACE is returned
Finally, IMyInterface is requested. I verify QueryInterface returns S_OK and sets (IMyInterface *)this as the interface pointer, as expected
So my confusion is why the calling CoCreateInstance is leaving me a NULL pointer and return code of E_NOINTERFACE, when the COM server app is clearly returning the interface I ask for?
EDIT: my client app calls CoInitialize(NULL) at startup, this makes no difference.
If your COM server is running in a different process, or a different apartment in the same process, COM needs to know how to package and transmit parameters when you make calls to your interface. This process is called "marshaling".
If you define a custom interface, you need to implement marshaling for it using one of the following approaches.
Standard marshaling: have the MIDL compiler to generate a proxy
and stub which you must register on the system. This is probably the best option since you have already defined your interface.
OLE Automation marshaling: you define an automation compatible
custom interface and use the
marshaller which is already part of
the COM framework
Custom marshaling: you implement the methods of IMarshal
When you are debugging your COM server, although you see that you are returning your custom interface in the call to QueryInterface, it does not make it across the process boundary because COM cannot figure out how to marshal that interface, hence the client sees E_NOINTERFACE.
UPDATE (based on your comment)
If this is an existing COM server app then you probably already have a proxy/stub. You need to register this on both the client and server. Could it be that you were testing this on a new machine(s) and you simply forgot to register this? To register you simply do regsvr32 on the proxy/stub dll.
This happens because COM subsystem tries to marshal your custom interface (IMyInterface) and simply has no idea how to do that. That happens either because the server is out-proc or because the server is in-proc and the thread of the consumer application that calls CoCreateInstance() has called CoInitialize()/ CoInitializeEx() incorrectly so that "multithreaded apartment" is requested as mentioned in the article user Thomas refers to in the other answer.
If you only need an in-proc server you could suppress marshalling by ensuring that the thread calling CoCreateInstance() either calls CoInitialize() or CoInitializeEx() with COINIT_APARTMENTTHREADED to enforce "single-threaded apartment".
If you need an out-proc server you can't get around marshalling. In the latter case you could do one of the following:
implement IMarshal - least preferable
add proxy/stubs and register them for your custom interface
(not sure if it will work for out-proc, but it's the simplest) if your interface can be marshalled with automation marshaller simply include a typlib into the resources of your COM server and register that typelib in the registry.
Could this be the threading model problem that Raymond Chen wrote about?
Edit in reply to the comment:
If your threading model is incompatible with the threading model of the object you're creating, then COM marshalling kicks in. And if the marshalling stuff isn't there, the error that comes out is E_NOINTERFACE, because the marshalling interface is missing.
It's more about threading models than about marshalling, really.
The previous comments about E_NOINTERFACE returned because marshalling interface is missing was very helpful,
however,
for us the answer/fix was to force the main application (the one calling CoCreateInstance) to be STA (single threaded apartment), and this was done by setting an advanced linker option, i.e.:
"CLR Thread Attribute" is set to "STA threading attribute"
or on the link command line you do:
"/CLRTHREADATTRIBUTE:STA"
This prevents a mix of MTA and STA, which causes a call across threads.
Hope someone else finds this helpful.