![]() |
Platforms, Frameworks & Libraries »
ATL »
General
Intermediate
License: The Code Project Open License (CPOL)
Global Interface Table: An Easy Way to Marshal an Interface PointerBy ThatsAlokAn easy way to marshal your interface pointer between threads! |
C++, C++/CLI, Windows, .NET, ATL, COM, VS.NET2003, VS2005, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
Component Object Modeling (COM) and ActiveX Template Library (ATL) are the toughest areas in Windows programming, but as a Windows programmer, you daily encounter these and seldom face difficulty accessing a COM pointer created in one thread from another thread in a multithreaded environment. COM/ATL has the concept of marshalling and the usage of Global Interface table to cope up with this problem.
Here, I am demonstrating how to marshal an interface pointer from one thread to another worker thread with some quick code. ATL provides an interfaces called IGlobalInterfaceTable and a COM template class called CComGITPtr to help the programmer understand this concept easily..
In my example, I have a COM component with an interface IIGitTest, which I am going to marshal in the GitClient application. If you don't know how to create the COM component, please refer to my Step-by-Step Guide for Creating a COM component.
IIGitTest with get/set property name and then create a MFC dialog based client application GitClient, which will access this interface from one apartment to another? GitInterface. I will import the DLL using a #import directive since I don't want the namespace in the imported tlh and tli files, so I will use the no_namepace suffix with #import. I.e., in our example:#import "..\\output\\GitInterface.dll" no_namespace
IIGitTestPtr m_pToInterface;
CoInitialize(NULL); // initialize the com CLSID pclsid; CLSIDFromString(L"GitInterface.IGitTest.1",&pclsid); m_pToInterface.CreateInstance(pclsid);
TCHAR szValues[256]; m_edtGitValue.GetWindowText(szValues,256); CComBSTR bstrValues(szValues); m_pToInterface->put_Value(bstrValues);
CComGITPtr<IIGITTEST> pToGITTest(m_pToInterface); DWORD dwGitCookie = pToGITTest.Detach();
You must be wondering what this dwGitCookie will do and how the template class is working? CComGITPtr is a template wrapper class, which encapsulates the IGlobalInterfaceTable interface. We are passing our interface pointer to the template class CComGITPtr, and in return it is returning the DWORD cookie, which will help us find our interface in the global interface table.
IIGitTest pointer from the Global Interface table. /// Create thread to try marshalling CreateThread(NULL,NULL,ThreadProc, reinterpret_cast<LPVOID>(dwGitCookie),NULL,NULL);
lpParam parameter.CoInitialize(NULL); DWORD dwCookie = reinterpret_cast<DWORD>(lpParam);
CComGITPtr object and pass dwCookie as the parameter, which will instruct the CComGITPtr object to search GIT and retrieve the interface pointer of our interface.CComGITPtr<IIGITTEST>pToGITTest(dwCookie);
CComGITPtr::CopyTO function.IIGitTest *pToGitPtr; pToGITTest.CopyTo(&pToGitPtr);
CComBSTR bstValue; pToGitPtr->get_Value(&bstValue); MessageBoxW(NULL,bstValue,L"From Git Interface",MB_OK);
The End :)
In this way, you can marshal an interface pointer from one thread to an other without thinking about the technicality of marshalling and other related stuff. Let us revise the process again.
DWORD cookie, find the interface in the GIT table | You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 1 Mar 2007 Editor: Smitha Vijayan |
Copyright 2007 by ThatsAlok Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |