1. 如何編寫 VC++代碼來使用COM組件
為了幫助讀者更快地體會到使用VC++編寫COM client的效果,我建議您從上訴鏈接中下載最新的release,並按照如下步驟搭一個簡單的測試環境:
Step1. 使用Visual Studio 2008打開CodeFx的solution文件(Visual Studio需要run as admin)。
Step2. Build其中的CppCOMClient和MFCCOMClient示例。由於項目依賴性的設置,這兩個VC++ example所依賴於的COM組件(CSDllCOMServer, ATLDllCOMServer, ATLExeCOMServer)也會被編譯並注冊。
Step3. 直接運行CppCOMClient,並得到如下輸出。CppCOMClient演示的是使用native C++來創建和使用進程內COM組件。這個COM組件既可以是用native代碼寫的,也可以是用.NET語言寫的。
Step4. 直接運行MFCCOMClient,並得到如下輸出。MFCCOMClient演示的是使用MFC的class wizard來創建並使用一個進程外的COM組件。
簡單的測試到此結束。下面我們來看看編寫一個VC++的程序來使用COM組件的一般方法:方法一:直接使用COM API,例如,CoCreateInstance以及IDispatch介面中定義的方法GetIDsOfNames,Invoke來創建和使用COM組件。當然,前提是那個COM組件支持IDispatch。CodeFx/CppCOMClient/RawAPI.cpp是該方法所對應的例子。
方法二:使用VC++的#import directive,導入目標COM組件的type library並自動生成一套包裝好的強類型的類和智能指針。這極大程度地方便了開發人員,因為生成的類和智能指針將復雜的COM API,類型轉換等內容都隱藏了起來,同時開發者還可以受益於Visual Studio的intellisense。CodeFx/CppCOMClient/ImportDirective.cpp是該方法所對應的例子。另外,值得注意的是,這個例子演示了使用一個.NET 寫的COM組件(CSDllCOMServer)。對於.NET寫的COM組件,我們額外需要#import mscorlib.tlb。
方法三:如果您開發的程序支持MFC,那您將更大程度地得益於MFC強大的class wizard。這個class wizard將方法二中的#import directive都封裝隱藏了。您只需輕點幾下滑鼠,便可以無縫透明地創建和使用COM組件,就好像他是一個普通的class一般。
2. COM組件的COM方法
COM是開發軟體組件的一種方法。組件實際上是一些小的二進制可執行程序,它們可以給應用程序,操作系統以及其他組件提供服務。開發自定義的COM組件就如同開發動態的,面向對象的API。多個COM對象可以連接起來形成應用程序或組件系統。並且組件可以在運行時刻,在不被重新鏈接或編譯應用程序的情況下被卸下或替換掉。Microsoft的許多技術,如ActiveX, DirectX以及OLE等都是基於COM而建立起來的。並且Microsoft的開發人員也大量使用COM組件來定製他們的應用程序及操作系統。
COM所含的概念並不止是在Microsoft Windows操作系統下才有效。COM並不是一個大的API,它實際上像結構化編程及面向對象編程方法那樣,也是一種編程方法。在任何一種操作系統中,開發人員均可以遵循「COM方法」。
一個應用程序通常是由單個的二進制文件組成的。當編譯器生成應用程序之後,在對下一個版本重新編譯並發行新生成的版本之前,應用程序一般不會發生任何變化。操作系統,硬體及客戶需求的改變都必須等到整個應用程序被重新生成。
這種狀況已經發生變化。開發人員開始將單個的應用程序分隔成單獨多個獨立的部分,也即組件。這種做法的好處是可以隨著技術的不斷發展而用新的組件取代已有的組件。此時的應用程序可以隨新組件不斷取代舊的組件而漸趨完善。而且利用已有的組件,用戶還可以快速的建立全新的應用。
傳統的做法是將應用程序分割成文件,模塊或類,然後將它們編譯並鏈接成一個單模應用程序。它與組件建立應用程序的過程(稱為組件構架)有很大的不同。一個組件同一個微型應用程序類似,即都是已經編譯鏈接好並可以使用的二進制代碼,應用程序就是由多個這樣的組件打包而得到的。單模應用程序只有一個二進制代碼模塊。自定義組件可以在運行時刻同其他的組件連接起來以構成某個應用程序。在需要對應用程序進行修改或改進時,只需要將構成此應用程序的組件中的某個用新的版本替換掉即可。
COM,即組件對象模型,是關於如何建立組件以及如何通過組件建立應用程序的一個規范,說明了如何可動態交替更新組件。
ActiveX與com組件
ActiveX是Microsoft對於一系列策略性面向對象程序技術和工具的稱呼,其中主要的技術是組件對象模型(COM)。在有目錄和其它支持的網路中,COM變成了分布式COM(DCOM)。在創建包括ActiveX程序時,主要的工作就是組件,一個可以自足的在ActiveX網路(網路主要包括Windows和Mac)中任意運行的程序。這個組件就是ActiveX控制項。ActiveX是Microsoft為抗衡Sun Microsystems的java技術而提出的,此控制項的功能和java applet功能類似。
如果您使用的是Windows操作系統,您或許會注意到一些以OCX結尾的文件。OCX代表「對象鏈接與嵌入控制項」(OLE),這個技術是Microsoft提出的程序技術,用於處理桌面文件的混合使用。COM的概念已經取代OLE的一部分,Microsoft也使用ActiveX控制項代表組件對象。
組件的一大優點就是可以被大多數應用程序再使用(這些應用程序稱為組件容器)。一個COM組件(ActiveX控制項 )可由不同語言的開發工具開發,包括C++和Visual Basic或PowerBuilder,甚至一些技術性語言如VBScript。
ActiveX控制項在Windows 95/NT和Macintosh中運行,Microsoft還准備支持UNIX的ActiveX控制項。
3. linux 下的 嵌入式C++ COM組件開發的一般步驟講解一下
明白你的意思
舉個例子吧
串口控制項COM
1----先寫好ARM的linux驅動程序
2-----然後把驅動程序打包成類
3----繼而改成QT的組件
4---然後以後就可以在QT開發的時候
直接引入這個組件並使用
4. 我用 visual studio 2005 編寫C# 的COM 組件 播放視頻 為什麼 打開不了 AVI格式的 文件
這與系統自帶的windows Meade player有關
因為你所用的控制項就是他提供的。所以換個高級版本的windows Meade player
5. com編程的COM編程入門
第一部分——什麼是COM,如何使用COM。
本文的目的是為剛剛接觸COM的程序員提供編程指南,並幫助他們理解COM的基本概念。內容包括COM規范簡介,重要的COM術語以及如何重用現有的COM組件。本文不包括如何編寫自己的COM對象和介面。
本文由淺入深描述COM的內在運行機制,教你如何使用第三方提供的COM對象(以Windows 外殼組件Shell為例)。讀完本文後,你就能掌握如何使用Windows操作系統中內建的組件和第三方提供的COM對象。
本文假設你精通C++語言。在例子代碼中使用了一點MFC和ATL,如果你不熟悉MFC和ATL也沒關系,本文會對這些代碼進行完全透徹的解釋。本文包括以下幾個部分:
簡單地說,COM是一種跨應用和語言共享二進制代碼的方法。與C++不同,它提倡源代碼重用。ATL便是一個很好的例證。源碼級重用雖然好,但只能用於C++。它還帶來了名字沖突的可能性,更不用說不斷拷貝重用代碼而導致工程膨脹和臃腫。
Windows使用DLLs在二進制級共享代碼。這也是Windows程序運行的關鍵——重用kernel32.dll, user32.dll等。但DLLs是針對C介面而寫的,它們只能被C或理解C調用規范的語言使用。由編程語言來負責實現共享代碼,而不是由DLLs本身。這樣的話DLLs的使用受到限制。
MFC引入了另外一種MFC擴展DLLs二進制共享機制。但它的使用仍受限制——只能在MFC程序中使用。
COM通過定義二進制標准解決了這些問題,即COM明確指出二進制模塊(DLLs和EXEs)必須被編譯成與指定的結構匹配。這個標准也確切規定了在內存中如何組織COM對象。COM定義的二進制標准還必須獨立於任何編程語言(如C++中的命名修飾)。一旦滿足了這些條件,就可以輕松地從任何編程語言中存取這些模塊。由編譯器負責所產生的二進制代碼與標准兼容。這樣使後來的人就能更容易地使用這些二進制代碼。
在內存中,COM對象的這種標准形式在C++虛函數中偶爾用到,所以這就是為什麼許多COM代碼使用C++的原因。但是記住,編寫模塊所用的語言是無關的,因為結果二進制代碼為所有語言可用。
此外,COM不是Win32特有的。從理論上講,它可以被移植到Unix或其它操作系統。但是我好像還從來沒有在Windows以外的地方聽說過COM。
6. com組件是什麼意思說什麼禁用了就不能在線看視頻了不知道什麼意思啊 謝謝~~~
你所用的在線看視頻是依賴這個COM組件,看視頻的使用,視頻程序會調用這個COM組件的一些功能(編解碼等)。如果禁用當然就看不了了。
7. 用C++編寫一個com組件,組件上有介面,怎麼編誰會
下面提供一個完全用C++實現的進程內(DLL)COM伺服器,不要ATL或MFC提供任何支持。用這種方式編寫COM對象可以讓你深入地洞察到COM處理進程內伺服器的方法以及COM是如何創建類工廠的。利用本文提供的這個簡單框架你可以實現很基本的COM組件,如外殼擴展(Shell Extensions)等。
以下是用本文所說的方式編寫自己的COM對象要經過的步驟:
第一步:寫一個頭文件,這個頭文件包含以下內容:
1、 包含文件comdef.h:#include 。
2、 定義COM伺服器的GUID。
_declspec(selectany) GUID CLSID_Mine = { 0xdc186800,
0x657f,
0x11d4,
{0xb0, 0xb5, 0x0, 0x50, 0xba, 0xbf, 0xc9, 0x4}
};
3、 給出介面的IID以及這個介面要實現的方法定義。到時客戶端會用到這個介面的IID和介面的方法。
interface __declspec(uuid("F614FB00-6702-11d4-B0B7-0050BABFC904")) ImyInterface : public IUnknown
{
STDMETHOD(Square)(long *pVal)PURE;
STDMETHOD(Cube)(long *pVal)PURE;
};
客戶端使用此介面:
HRESULT hr;
ImyInterface *pmine=(0);
hr = CoCreateInstance(CLSID_Mine, // COM 伺服器的CLSID
NULL,//不支持聚合
CLSCTX_INPROC_SERVER, // 是個DLL
__uuidof(ImyInterface), // 介面的IID
(void**)&pmine
);
還有一種方法可以從注冊表中獲得COM對象的CLSID,就是調用CLSIDFromProgId()函數,不過必須把組件的ProgId傳遞給這個函數。
第二步:必須為所定義的介面提供實現,本文用的方法是創建一個從介面繼續的新類:
// 這個類實現單介面ImyInterface ...
//
//
class CmyInterface : public CComBase<> ,
public InterfaceImpl
{
public:
CmyInterface();
virtual ~CmyInterface();
// 我們必須要為QueryInterface 編寫代碼
STDMETHOD(QueryInterface)(REFIID riid,LPVOID *ppv);
// ImyInterface 介面方法
STDMETHOD(Square)(long *pVal);
STDMETHOD(Cube)(long *pVal);
};
模版類InterfaceImpl<>提供介面引用計數的實現。在此我們可以用多介面繼續,那樣就能在一個COM組件中實現多個介面。
第三步:在完成這個對象之前,我們還要編寫Queryinterface和兩個介面方法:
STDMETHODIMP CmyInterface::QueryInterface(REFIID riid,LPVOID *ppv)
{
*ppv = NULL;
if(IsEqualIID(riid,IID_IUnknown) IsEqualIID(riid,__uuidof(ImyInterface)))
{
// 因為我們從ImyInterface繼續,所以要進行強制類型轉換
*ppv = (ImyInterface *) this;
_AddRef(); // 這個方法從某個基類繼續而來
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP CmyInterface::Square(long *pVal)
{
long value = *pVal;
*pVal = value * value;
return S_OK;
}
STDMETHODIMP CmyInterface::Cube(long *pVal)
{
long value = *pVal;
*pVal = value * value * value;
return S_OK;
}
注重這里使用了__uuidof(ImyInterface)來獲取介面的IID,這是因為我們已經在第一步中將這個介面關聯到了某個uuid。
最後一步:COM 組件的DLLs必須輸出一個叫DllGetClassObject的函數。由這個函數為CmyInterface創建類工廠並返回一個對它的引用。然後我們調用CoCreateInstance為進程內COM創建類工廠,接著調用DllGetClassObject。這個類工廠有一個方法是CreateInstance,由這個方法創建對象並返回對它的引用。
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
*ppvOut = NULL;
if (IsEqualIID(rclsid, CLSID_Mine))
{
// 為CmyInterface類聲明類工廠
CClassFactory
*pcf = new CClassFactory;
return pcf->QueryInterface(riid,ppvOut);
}
return CLASS_E_CLASSNOTAVAILABLE;
}
在此我們要檢查所請求的CLSID是不是CLSID_Mine,假如不是則返回一個錯誤代碼。
你可能會問在哪裡創建實際的CmyInterface類對象,實際上這是由CClassFactory的模板實例來處理的。以下是CClassFatory的實現:
// CSingleCreator 用於單實例類工廠,這個類為多個CreateObject請求返回相同的對象指針..
template
class CSingleCreator
{
protected:
CSingleCreator():m_pObj(0) {};
comObj *CreateObject()
{
if(!m_pObj)
{
m_pObj = new comObj;
}
return m_pObj;
}
comObj * m_pObj;
};
// CMultiCreator 用於常用類工廠,這個類為每一個CreateObject請求返回新的對象指針..
template
class CMultiCreator
{
protected:
CMultiCreator():m_pObj(0) {};
comObj *CreateObject()
{
return new comObj;
}
comObj * m_pObj;
};
//ClassFactory類實現
// MultiCreator是預設的類工廠創建者
//這個類實現了介面IclasFactory......
class CClassFactory : public CComBase<>,
public InterfaceImpl,
public creatorClass
{
public:
CClassFactory() {};
virtual ~CClassFactory() {};
STDMETHOD(QueryInterface)(REFIID riid,LPVOID *ppv)
{
*ppv = NULL;
if(IsEqualIID(riid,IID_IUnknown) IsEqualIID(riid,IID_IClassFactory))
{
*ppv = (IClassFactory *) this;
_AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
{
*ppvObj = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
m_pObj = CreateObject(); // m_pObj 在creatorClass中定義
if (!m_pObj)
return E_OUTOFMEMORY;
HRESULT hr = m_pObj->QueryInterface(riid, ppvObj);
if(hr != S_OK)
{
delete m_pObj;
}
return hr;
}
STDMETHODIMP LockServer(BOOL) {return S_OK; } // 未實現
};
COM調用CreateInstance創建請求的對象,參數riid指的是所請求的介面IID,假如這個對象支持這個介面,則增加它的引用計數並返回對自身的引用。
關於代碼:本文所提出的方法是如何用純粹的C++編寫COM組件的一個大概念。很多方面的細節都省略了。從本文的文字和代碼中可以看出用純C++編寫COM組件需要做些什麼工作,假如你要用這種方法編寫COM組件的話,這些代碼只能是拋磚引玉,具體的實現可以在此基礎上往下做.......。