Passing an interface through an ATL interface
-
Hey Gang, I am on the verge of panic today because I need to quickly develop a solution for a distributed analysis program. Thanks for taking the time to respond if you get a chance. I have an exe that uses an XML DOM to represent the status of a system. The DOM is wrapped in an ATL interface that provides some convenience routines for manipulating the data in the DOM. For discussion I am going to refer to the ATL interface as the CurrentStateInterface. I would like to share access across computers to an instance of the CurrentStateInterface. Ideally remote systems would be able to connect to the server application through an ATL interface and request the CurrentStateInterface. Once the interface is marshalled to the remote system, the remote system could make calls to the CurrentStateInterface which would manipulate the data in the DOM on the server. I have read a few articles from the MSDN. One article suggested several possible solutions: Singleton objects, File monikers, CoMarshlInterface/CoUnMarshalInteface, Custom class objects, Custom monikers. I know some of these would work better than others. From what I have read, the file monikers look like an appropriate solution but I would look to someone with more experience for guidance. I am hoping that someone has done something similar and can share his/her knowledge and experience. Any good suggested reading would be appreciated also. Thanks very much for your time! Hawk
-
Hey Gang, I am on the verge of panic today because I need to quickly develop a solution for a distributed analysis program. Thanks for taking the time to respond if you get a chance. I have an exe that uses an XML DOM to represent the status of a system. The DOM is wrapped in an ATL interface that provides some convenience routines for manipulating the data in the DOM. For discussion I am going to refer to the ATL interface as the CurrentStateInterface. I would like to share access across computers to an instance of the CurrentStateInterface. Ideally remote systems would be able to connect to the server application through an ATL interface and request the CurrentStateInterface. Once the interface is marshalled to the remote system, the remote system could make calls to the CurrentStateInterface which would manipulate the data in the DOM on the server. I have read a few articles from the MSDN. One article suggested several possible solutions: Singleton objects, File monikers, CoMarshlInterface/CoUnMarshalInteface, Custom class objects, Custom monikers. I know some of these would work better than others. From what I have read, the file monikers look like an appropriate solution but I would look to someone with more experience for guidance. I am hoping that someone has done something similar and can share his/her knowledge and experience. Any good suggested reading would be appreciated also. Thanks very much for your time! Hawk
Hawk, You did not mention whether or not the existing interface is free threaded or not. If it is free threaded, I would think you could create a service executable that would run as an ATL server. I think you would have to implement it as a singleton object (so that every instance was the same instance). Access across a network would then be possible by specifying what machine to create the instance on. If the interface is apartment threaded, I would create a batch of worker threads, create one instance of the CurrentStateInterface in the main thread, then upon thread initialization, marshal the interface across, and make sure all access to the object (in any thread) is protected through a global critical section. Your main thread would be dispatching messages to your worker thread, which would do the core of the processing, returning the results from the CurrentStateInterface and maintaining state information across different sessions. If the CurrentStateInterface is apartment threaded, I think you have a bit of work ahead of you, if it is free threaded, I'm pretty sure it'll be a straight forward thing (make sure your using the free threaded version of the XML DOM!). Hope that helps. Mark
-
Hawk, You did not mention whether or not the existing interface is free threaded or not. If it is free threaded, I would think you could create a service executable that would run as an ATL server. I think you would have to implement it as a singleton object (so that every instance was the same instance). Access across a network would then be possible by specifying what machine to create the instance on. If the interface is apartment threaded, I would create a batch of worker threads, create one instance of the CurrentStateInterface in the main thread, then upon thread initialization, marshal the interface across, and make sure all access to the object (in any thread) is protected through a global critical section. Your main thread would be dispatching messages to your worker thread, which would do the core of the processing, returning the results from the CurrentStateInterface and maintaining state information across different sessions. If the CurrentStateInterface is apartment threaded, I think you have a bit of work ahead of you, if it is free threaded, I'm pretty sure it'll be a straight forward thing (make sure your using the free threaded version of the XML DOM!). Hope that helps. Mark
Mark, Thanks for the great response. I will work in the direction you have suggested. I am kind of weak in the COM thread model details. I have created my CurrentStateInterface with the VC++ default attributes which is apartment. Do I need to reimplement the interface through class wizard as free threaded or is there an easier way to change the threading model? It seems fairly trivial to make a singleton object and to instantiate the free threaded version of the XML DOM. Do you know of any example code that is implemented like you have laid out, with a singleton object? Thanks again for the great information!
-
Mark, Thanks for the great response. I will work in the direction you have suggested. I am kind of weak in the COM thread model details. I have created my CurrentStateInterface with the VC++ default attributes which is apartment. Do I need to reimplement the interface through class wizard as free threaded or is there an easier way to change the threading model? It seems fairly trivial to make a singleton object and to instantiate the free threaded version of the XML DOM. Do you know of any example code that is implemented like you have laid out, with a singleton object? Thanks again for the great information!
You do not need to rerun the class wizard to change the threading model from apartment to free threaded. I believe you can find this under registry resource for your project (just change where it says 'apartment' or 'both' to 'free'), after you make the change be sure to re-register the interface. As far as creating a singleton object is concerned, there is an ATL macro 'DECLARE_CLASSFACTORY_SINGLETON' which should do the trick for you, the macro basically specifies that the class CComClassFactorySingleton will be the object which is queried upon every call to CreateInstance allowing a single instance to be passed for each call. The only caveat is that you must make sure that the CurrentStateInterface is thread safe. This means protecting access to any shared objects or data (by shared, I mean objects that may be modified across threads). If everything is strictly read only, I don't think you have anything to worry about, but if you are modifying data, you must make sure you wrap these parts of the program in critical sections to correctly synchronize access these to objects. Unfortunately, I don't have any code which I am able to share with you implementing singleton objects. There should be many examples however in MSDN. Do a search on the DECLARE_CLASSFACTORY_SINGLETON macro and see what you come up with. Cheers!