|
Hi,
I have two questions :
1) How would you create a singleton ATL COM Class? (Like when you do a CoCreateInstace for the interface, you always get the same instance of the class)
Right now I did a work around of declaring all the data as static variables.
I also read about a macro called as DECLARE_SOMETHING_SINGLETON (Not sure about the correct name)
2) I also have some global functions in the same COM Class. These global functions need to access the COM Class member functions. So the global functions need to access only the single instance of this COM Class at any cost. My COM Component is an Out-Proc Win NT Service.
The global function code looks like
CALLBACK Global_Fn()
{
//call the class's function
CCOMCLASSA *pA = NULL;
pA->MemberFunA(); //this is crap piece of code, but due to static vbles, it is working as of now
}
Any ideas to do all this elegantly? All help will be greatly appreciated.
Thanks
Misha
|
|
|
|
|
1. You're thinking of the DECLARE_CLASSFACTORY_SINGLETON macro. You'd use it like this:
class ATL_NO_VTABLE CYourClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Csadfas, &CLSID_sadfas>,
public IDispatchImpl<Isadfas, &IID_IBlah, &LIBID_ATLPROJLib>
{
DECLARE_CLASSFACTORY_SINGLETON(CYourClass)
2. Given that the class factories have been registered (it's an .EXE server) using the CoRegisterClassObject API you can safely and efficiently implement your globals like this:
void MyGlobal()
{
CComPtr<IMyInterface> spInt;
if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) )
{
spInt->YourMethod();
}
}
Steve
|
|
|
|
|
Thanks Steve
|
|
|
|
|
I am again into dilemma here. I am sorry, very new to COM programming.
The problem is:
I have two kinds of functions in my COM class.
1) Functions that are exposed via the interface
2) Internal routines of the COM class which the global functions/main program may need to call
So if I am creating a COM Class, does it mean that the only link to my COM Class should be via the interface routines? i.e. all the internal routines which require to be called by the global functions also need to be exposed as interface routines?
So what I gather from this is that if somebody wants to access your COM Class (from anywhere, say the winmain routine of your service or some global function in your COM Class itself etc), it has to be via the interface pointer only.
Any help greatly appreciated.
Thanks & Regards,
Misha
|
|
|
|
|
The easiest way (not pretty to look at) is to make your functions look like this:
void MyGlobal()
{
CComPtr<IMyInterface> spInt;
if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) )
{
CYourClass* pClass = static_cast<CYourClass*>(spInt.p);
pClass->YourMethod();
}
}
Steve
|
|
|
|
|
I think it won't work that way. Maybe (and I'm not sure) only if the COM object is created within the same process. In that case you could do like:
CYourClass * pClass = new CYourClass();
instead of creating any com object.
|
|
|
|
|
I was assuming that the globals you were talking about where in the COM server - In which case the technique I gave will work. You couldn't just create a new class each time because it wouldn't be a singleton in this case. If the global you're talking about are meant to be in the client then this technique will not work - But in that case the only real solution is to expose the functionality as COM interfaces.
Steve
|
|
|
|
|
Thanks Stephen,
I was looking all over the internet for an answer to this. And to say it was just a macro DECLARE_CLASSFACTORY_SINGLETON.
|
|
|
|
|
Glad to be of help. A 2006 post I notice....
Steve
|
|
|
|
|
Can anyone tell me how to use CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR clip board formats in file Drag and Drop?
Thanks and regards,
Anil
|
|
|
|
|
Is there other way to use COM library in a managed code without registration with regsvr32 util on a server? The problem issues from an installation application on a server. I am developing web application and can only upload sources. But how can I register COM library?
Thanks for any advice.
|
|
|
|
|
Hi,
I have gone through and added a COleProperlyPage to a ActiveX Control I have to make. I have two property pages, the first one was already in the ActiveX Control, I have a string in a textbox in the property page that I need to update and send to the second COlePropertyPage.
I am using DDP_Text( ... ) and it works for the first time so the second propertypage gets the correct result, but then I go back to the first ColePropertyPage and change the text string and it doesnt update when I click the tab to go back to the other COlePropertyPage.
Does anyone know what is going on here.
Thanks in advance
|
|
|
|
|
hi
could anyone post the link to download COM specification??
i searched Microsoft website but didn't get the exact link..
thanx in advance
|
|
|
|
|
|
I need to pass a c++ object to the COM client. I saw a few articles on the same.
But those were objects in which there was just a single memeber. I need to pass a
c++ object which has several subclasses as its members.
If anyone could shed some light on this it would be very helpful.
Thanks in advance,
ann
|
|
|
|
|
In short, you don't. COM is designed to be langauge neutral, as such it only knows about COM objects, not C++ objects. Can you give more details? If so I may be able to be more helpful!
Steve
|
|
|
|
|
thanks for the response steve..
I can give u the exact situation..
Say i have a class clsA
class clsA
{
public:
clsB obj1; //class B obj
clsC obj2; //class C obj
char name[10];
void show();
}
Now if i create an object of clsA say obj3, is it possible to pass
obj3 to the COM client. Please let me know if there is a way to do this
even if its twisted...
ann
|
|
|
|
|
It's possible, but the solutions are definately "twisted", I would suggest they are worse then the problem. You could do this:
class clsA
{
public:
clsB obj1;
clsC obj2;
char name[10];
void show();
};
HRESULT DirtyHack_PassInCPPObject([in]INT_PTR pObj);
STDMETHODIMP CYouCOMObject::DirtyHack_PassInCPPObject(INT_PTR pObj)
{
clsA* pA = reinterpret_cast<clsA*>(pObj);
return S_OK;
}
clsA a;
spObj->DirtyHack_PassInCPPObject(reinterpret_cast<INT_PTR>(&a));
As you've probably guessed, I do not approve of this - But you wanted twisted. None of your coworkers will thank you for putting this in production code - If I were a manager I'd fire someone for doing so. COM objects written in any language can be called from any other language, this is one of the reasons for using COM. Breaking the rules like this destroys all this.
Steve
|
|
|
|
|
You are right steve... its real twisted...
but u think such a situation never comes..? like the need to pass a collection
of values which are dependent on each other..? If such a situation comes, wat is the
perfect way to do it..?
thanks,
ann
|
|
|
|
|
Model the data as a COM object. Once that's done you can consume the data from any COM compatible langauge. e.g. C/C++, JavaScript, VB, any of the dotNET langauges, etc......
Steve
|
|
|
|
|
sorry to bug u again steve...But can u explain a bit more on modelling the data a COM object
using the example i gave before as i am pretty new to COM..
Ann
|
|
|
|
|
It would help if I knew how the COM server was implemented. Does it use ATL, MFC, etc....
Steve
|
|
|
|
|
yup... currently it is done using ATL...
Ann
|
|
|
|
|
annjose24 wrote: Now if i create an object of clsA say obj3, is it possible to passobj3 to the COM client.
The "clean" way to do that is implementing COM objects to expose the funcionality of clsA, clsB and clsC. So you will have IClsA implemented by clsA, IClsB implemented by clsB, and so on...
Then, instead of passing the object, you can pass the interface via COM. In your current COM object you need a method like:
(I suppose that you have a pointer to an object of type ClsA in your COM object called m_pClsa)
HRESULT CYourCOMObject::GetObjectClsA ( IClsA ** ppObjClsA)
{
HRESULT hr = m_pClsa->QueryInterface(IID_IClsa, (void**)ppObjClsA);
if (SUCCEEDED(hr))
return S_OK
*ppObjClsa = NULL;
return S_FALSE;
}
The same methods for ClsB and ClsC should be in ClsA.
Do you get the idea more or less?
Regards.
|
|
|
|
|
As Stephen said, you can't, but you have the alternative of modeling the objects you want to pass with COM interfaces, as you can pass via COM that interfaces. I'm not sure if I was clear... This alternative is much more tedious but is better than nothing.
Regards.
|
|
|
|