• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級(jí)} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

            C++ COM

             

            前言:為了介紹C#寫界面,C++寫算法的快捷交互開(kāi)發(fā)方式,首先介紹c++,C#內(nèi)部的DLL,COM調(diào)用。

            一,COM
            COM (Component Object Model),微軟為提高代碼的可從用性而開(kāi)發(fā)的組件對(duì)象模型的軟件架構(gòu),在windows系統(tǒng)的開(kāi)發(fā)中大量的使用了這種技術(shù),使用這種技術(shù)我們盡可能的把我們的軟件劃分位許多組件,通過(guò)組件的組合調(diào)用最總實(shí)現(xiàn)軟件的目的,COM的使用不僅大大的提高了代碼的可從用性,而且減小了代碼間的耦合。更多的關(guān)于OLE,COM,COM+,DCOM,ActiveX的概念

            二,COM的創(chuàng)建
            一般COM的創(chuàng)建有2中方法,使用ATL Wizard 和不使用ATL。

            1)使用ATL Wizard創(chuàng)建COM非常的簡(jiǎn)單,可以參考下面2個(gè)鏈接,分別使用ATL6.0和ATL7.0,最新的類似:
                 ATL7.0 COM: http://www.codeproject.com/atl/SimpleDlls.asp
                 ATL6.0 com: http://www.codeproject.com/atl/com_atl.asp

            2)不使用ATL,當(dāng)然更沒(méi)有Wizard,只有手動(dòng)的一步一步的實(shí)現(xiàn),不過(guò)這也是學(xué)習(xí)COM最好的方法和必經(jīng)之路。可以參考:
                 http://www.codeproject.com/com/LocalCOMServerClient.asp
                具體的步驟如下:
                1)建立一個(gè)Win32的DLL。例如CarLocalServer。
                2)首先加入IDL接口描述文件CarLocalServerTypeInfo.idl,編譯后會(huì)生成4個(gè)文件CarLocalServerTypeInfo_h.h,CarLocalServerTypeInfo_i.cpp,CarLocalServerTypeInfo_p.cpp,      dlldata.cpp 。
                

            import "oaidl.idl";
            import 
            "ocidl.idl";

            // define IStats interface
            [
            object, uuid(FE78387F-D150-4089-832C-BBF02402C872),
             oleautomation, helpstring(
            "Get the status information about this car")]
            interface IStats : IUnknown
            {
               HRESULT DisplayStats();
               HRESULT GetPetName([out,retval] BSTR
            * petName);
            };

            // define the IEngine interface
            [
            object, uuid(E27972D8-717F-4516-A82D-B688DC70170C),
             oleautomation, helpstring(
            "Rev your car and slow it down")]
            interface IEngine : IUnknown
            {
               HRESULT SpeedUp();
               HRESULT GetMaxSpeed([out,retval] 
            int* maxSpeed);
               HRESULT GetCurSpeed([out,retval] 
            int* curSpeed);
            };

            // define the ICreateMyCar interface
            [
            object, uuid(5DD52389-B1A4-4fe7-B131-0F8EF73DD175),
             oleautomation, helpstring(
            "This lets you create a car object")]
            interface ICreateMyCar : IUnknown
            {
               HRESULT SetPetName([in]BSTR petName);
               HRESULT SetMaxSpeed([in] 
            int maxSp);
            };

            // library statement
            [uuid(957BF83F
            -EE5A-42eb-8CE5-6267011F0EF9), version(1.0),
             helpstring(
            "Car server with typeLib")]
            library CarLocalServerLib
            {
               importlib(
            "stdole32.tlb");
               [uuid(1D66CBA8
            -CCE2-4439-8596-82B47AA44E43)]
               coclass MyCar
               {
                  [default] interface ICreateMyCar;
                  interface IStats;
                  interface IEngine;
               };
            };


                3) 加入生命周期管理類managesycle.h
             

            #pragma once

            class CManageSycle
            {
            public:
                CManageSycle(void);
                ~CManageSycle(void);

                static void InObject()  {
            ++m_nObject;}
                static void DeObject()  {
            --m_nObject;}
                static bool IsZeroObject() { return m_nObject
            ==0 ;}
                static void InLock()  {
            ++m_nLock;}
                static void DeLock()  {
            --m_nLock;}
                static bool IsZeroLock() { return m_nLock
            ==0 ; }
            private:
                static ULONG m_nObject;
                static ULONG m_nLock;
            };

            managesycle.cpp實(shí)現(xiàn)文件:

            #include "StdAfx.h"
            #include 
            "managesycle.h"
            ULONG CManageSycle::m_nObject
            =0;
            ULONG CManageSycle::m_nLock
            =0;
            CManageSycle::CManageSycle(void)
            {
            }

            CManageSycle::~CManageSycle(void)
            {
            }


                4)加入真正的com的接口的實(shí)現(xiàn)類,MyCar.h (除了實(shí)現(xiàn)COM的接口,還必須實(shí)現(xiàn)IUnKnown接口)


            #pragma once

            #include 
            "unknwn.h"
            #include 
            "CarLocalServerTypeInfo_h.h"

            const int MAX_SPEED = 500;
            const int MAX_NAME_LENGTH = 20;

            class MyCar : 
                
            public IEngine, 
                
            public ICreateMyCar, 
                
            public IStats  
            {
            public:
                MyCar();
                virtual ~MyCar();

                
            // IUnknown
                STDMETHODIMP QueryInterface(REFIID riid, void
            ** pIFace);
                STDMETHODIMP_(DWORD)AddRef();
                STDMETHODIMP_(DWORD)Release();

                
            // IEngine
                STDMETHODIMP SpeedUp();
                STDMETHODIMP GetMaxSpeed(
            int* maxSpeed);
                STDMETHODIMP GetCurSpeed(
            int* curSpeed);
                
                
            // IStats
                STDMETHODIMP DisplayStats();
                STDMETHODIMP GetPetName(BSTR
            * petName);

                
            // ICreateMyCar
                STDMETHODIMP SetPetName(BSTR petName);
                STDMETHODIMP SetMaxSpeed(
            int maxSp);

            private:
                DWORD    m_refCount;
                BSTR    m_petName;
                
            int        m_maxSpeed;
                
            int        m_currSpeed;
            };



            MyCar.cpp

            #include "stdafx.h"
            #include 
            <stdio.h> 

            #include 
            "CarLocalServerTypeInfo_i.c"
            #include 
            "MyCar.h"
            #include 
            "ManageSycle.h"

            //////////////////////////////////////////////////////////////////////
            // Construction/Destruction
            //////////////////////////////////////////////////////////////////////
            MyCar::MyCar() : m_refCount(
            0), m_currSpeed(0), m_maxSpeed(0)
            {
                m_refCount
            =0;
                CManageSycle::InObject();
                m_petName 
            = SysAllocString(L"Default Pet Name");
                
            }

            MyCar::~MyCar()
            {
                CManageSycle::DeObject();
                
            if(m_petName) SysFreeString(m_petName);
                MessageBox(
            NULL,
                L
            "MyCar is being distructed. Make sure you see this message, if not, you might have memory leak!",
                L
            "Destructor",MB_OK | MB_SETFOREGROUND);
            }

            // IUnknown
            STDMETHODIMP MyCar::QueryInterface(REFIID riid, void
            ** pIFace)
            {
                
            // Which aspect of me do they want?
                
            if(riid == IID_IUnknown)
                {
                    
            *pIFace = (IUnknown*)(IEngine*)this;
                    
            // MessageBox(NULL"Handed out IUnknown","QI",MB_OK | MB_SETFOREGROUND);
                }
                
                
            else if(riid == IID_IEngine)
                {
                    
            *pIFace = (IEngine*)this;
                    
            // MessageBox(NULL"Handed out IEngine","QI",MB_OK | MB_SETFOREGROUND);
                }
                
                
            else if(riid == IID_IStats)
                {
                    
            *pIFace = (IStats*)this;
                    
            // MessageBox(NULL"Handed out IStats","QI",MB_OK | MB_SETFOREGROUND);
                }
                
                
            else if(riid == IID_ICreateMyCar)
                {
                    
            *pIFace = (ICreateMyCar*)this;
                    
            // MessageBox(NULL"Handed out ICreateMyCar","QI",MB_OK | MB_SETFOREGROUND);
                }
                
            else
                {
                    
            *pIFace = NULL;
                    return E_NOINTERFACE;
                }

                ((IUnknown
            *)(*pIFace))->AddRef();
                return S_OK;
            }

            STDMETHODIMP_(DWORD) MyCar::AddRef()
            {
                
            ++m_refCount;
                return m_refCount;
            }

            STDMETHODIMP_(DWORD) MyCar::Release()
            {
                
            if(--m_refCount == 0)
                {
                    delete this;
                    return 
            0;
                }
                
            else
                    return m_refCount;
            }

            // IEngine
            STDMETHODIMP MyCar::SpeedUp()
            {
                m_currSpeed 
            += 10;
                return S_OK;
            }

            STDMETHODIMP MyCar::GetMaxSpeed(
            int* maxSpeed)
            {
                
            *maxSpeed = m_maxSpeed;
                return S_OK;
            }

            STDMETHODIMP MyCar::GetCurSpeed(
            int* curSpeed)
            {
                
            *curSpeed = m_currSpeed;
                return S_OK;
            }


            // IStats
            STDMETHODIMP MyCar::DisplayStats()
            {
                
            // Need to transfer a BSTR to a char array.
                char buff[MAX_NAME_LENGTH];
                WideCharToMultiByte(CP_ACP, 
            NULL, m_petName, -1, buff, 
                                    MAX_NAME_LENGTH, 
            NULLNULL);

                
            //MessageBox(NULL, buff, L"Pet Name",MB_OK | MB_SETFOREGROUND);
                memset(buff, 
            0, sizeof(buff));
                sprintf(buff, 
            "%d", m_maxSpeed);
                
            //MessageBox(NULL, buff,L"Max Speed", MB_OK| MB_SETFOREGROUND);
                return S_OK;
            }

            STDMETHODIMP MyCar::GetPetName(BSTR
            * petName)
            {
                
            *petName = SysAllocString(m_petName);
                return S_OK;
            }


            // ICreateMyCar
            STDMETHODIMP MyCar::SetPetName(BSTR petName)
            {
                SysReAllocString(
            &m_petName, petName);
                return S_OK;
            }

            STDMETHODIMP MyCar::SetMaxSpeed(
            int maxSp)
            {
                
            if(maxSp < MAX_SPEED)
                    m_maxSpeed 
            = maxSp;
                return S_OK;
            }


                5)加入工廠類MyCarClassFactory.h,(實(shí)現(xiàn)IUnKnown接口和IClassFactory接口)

            // the class object (class factory) for CoMyCar class

            #pragma once

            class MyCarClassFactory : 
            public IClassFactory
            {
            public:
                MyCarClassFactory();
                virtual ~MyCarClassFactory();

                
            // IUnknown
                STDMETHODIMP QueryInterface(REFIID riid,void
            ** pIFace);
                STDMETHODIMP_(ULONG)AddRef();
                STDMETHODIMP_(ULONG)Release();

                
            // IClassFactory
                STDMETHODIMP LockServer(BOOL fLock);
                STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter,REFIID riid,void
            ** ppv);

            private:

                ULONG m_refCount;

            };

            MyCarClassFactory.cpp

            #include "stdafx.h"
            #include 
            "MyCar.h"
            #include 
            "MyCarClassFactory.h"
            #include 
            "locks.h"
            #include 
            "ManageSycle.h"

            MyCarClassFactory::MyCarClassFactory()
            {
                m_refCount 
            = 0;
            }

            MyCarClassFactory::~MyCarClassFactory()
            {
                MessageBox(
            NULL,
                L
            "MyCarClassFactory is being distructed. Make sure you see this message, if not, you might have memory leak!",
                L
            "Destructor",MB_OK | MB_SETFOREGROUND);
            }

            STDMETHODIMP_(ULONG) MyCarClassFactory::AddRef()
            {
                
            //return ++m_refCount;
                return 
            10;
            }

            STDMETHODIMP_(ULONG) MyCarClassFactory::Release()
            {
                
            /*
                
            if ( --m_refCount == 0 )
                {
                    delete this;
                    return 
            0;
                }
                return m_refCount;
                
            */
                return 
            20;
            }

            STDMETHODIMP MyCarClassFactory::QueryInterface(REFIID riid,void
            ** pIFace)
            {
                
            if ( riid == IID_IUnknown )
                    
            *pIFace = (IUnknown*)this;
                
            else if ( riid == IID_IClassFactory )
                    
            *pIFace = (IClassFactory*)this;
                
            else
                {
                    
            *pIFace = NULL;
                    return E_NOINTERFACE;
                }
                ((IUnknown
            *)(*pIFace))->AddRef();
                return S_OK;
            }

            STDMETHODIMP MyCarClassFactory::LockServer(BOOL fLock)
            {
                (VARIANT_TRUE 
            == fLock) ? CManageSycle::InLock() : CManageSycle::DeLock();
                return S_OK;
            }

            STDMETHODIMP MyCarClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,REFIID riid,void
            ** ppv)
            {
                
            if ( pUnkOuter != NULL ) return CLASS_E_NOAGGREGATION;

                MyCar
            * pMyCarObj = NULL;
                HRESULT hr;

                pMyCarObj 
            = new MyCar();
                hr 
            = pMyCarObj->QueryInterface(riid,ppv);

                
            if ( FAILED(hr) ) delete pMyCarObj;
                return hr;
            }


                6)實(shí)現(xiàn)COM入口和自注冊(cè)函數(shù)CarLocalServer.cpp,

            // CarLocalServer.cpp : Defines the entry point for the DLL application.
            //

            #include 
            "stdafx.h"
            #include 
            <iostream>    
            #include 
            <string.h>

            #include 
            "CarLocalServerTypeInfo_h.h"
            //#include "CarLocalServerTypeInfo_i.c"
            #include 
            "MyCarClassFactory.h"    
            #include 
            "ManageSycle.h"

            using namespace std;

            #ifdef _MANAGED
            #pragma managed(push, off)
            #endif

            HMODULE g_hmodule;

            BOOL APIENTRY DllMain( HANDLE hModule, 
                                   DWORD  ul_reason_for_call, 
                                   LPVOID lpReserved
                                 )
            {
                g_hmodule 
            = static_cast<HMODULE>(hModule);
                return 
            TRUE;
            }


            STDAPI DllCanUnloadNow()
            {
                bool bDllCanUnloadNow 
            = CManageSycle::IsZeroObject() && CManageSycle::IsZeroLock();
                return bDllCanUnloadNow ? S_OK : S_FALSE;
            }

            STDAPI DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID
            * ppv)
            {
                
            *ppv = NULL;
                
            if(__uuidof(MyCar) != rclsid)
                {
                    return E_NOINTERFACE;
                }

                MyCarClassFactory
            * pBirdFactory = new MyCarClassFactory();
                
            if(NULL == pBirdFactory)
                {
                    return E_OUTOFMEMORY;
                }

                HRESULT hr 
            = pBirdFactory->QueryInterface(riid,ppv);
                
            if(FAILED(hr))
                {
                    delete pBirdFactory;
                }
                return hr;
            }

            STDAPI DllRegisterServer()
            {
                HKEY hRoot, hNew;
                ::RegOpenKey(HKEY_CLASSES_ROOT,L
            "CLSID",&hRoot);
                ::RegCreateKey(hRoot,L
            "{1F0A9759-FCBE-4870-8336-971BD19A7452}\\InprocServer32",&hNew);
                wchar_t strFile[MAX_PATH];
                ::GetModuleFileName(g_hmodule,strFile,MAX_PATH);
                ::RegSetValue(hNew,
            NULL,REG_SZ,strFile,MAX_PATH);
                ::RegCloseKey(hRoot);
                return S_OK;
            }

            STDAPI DllUnregisterServer()
            {
                HKEY hRoot;
                ::RegOpenKey(HKEY_CLASSES_ROOT,L
            "CLSID",&hRoot);
                ::RegDeleteKey(hRoot,L
            "{1F0A9759-FCBE-4870-8336-971BD19A7452}");
                ::RegDeleteKey(hRoot,L
            "{1F0A9759-FCBE-4870-8336-971BD19A7452}\\InprocServer32");
                ::RegCloseKey(hRoot);
                return S_OK;
            }
            #ifdef _MANAGED
            #pragma managed(pop)
            #endif


                7)增加def到處文件CarLocalServer.def,

            LIBRARY    "CarLocalServer"

            EXPORTS
                DllCanUnloadNow                
            PRIVATE
                DllGetClassObject               
            PRIVATE
                DllRegisterServer               
            PRIVATE
                DllUnregisterServer            
            PRIVATE


              

            三,COM的調(diào)用過(guò)程
            通過(guò)一個(gè)創(chuàng)建COM組件的最小框架結(jié)構(gòu),然后看一看其內(nèi)部處理流程是怎樣的

                IUnknown *pUnk=NULL;
                IObject *pObject=NULL;
                CoInitialize(NULL);
                CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);
                pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
                pUnk->Release();
                pObject->Func();
                pObject->Release();
                CoUninitialize();

            這就是一個(gè)典型的創(chuàng)建COM組件的框架,不過(guò)我的興趣在CoCreateInstance身上,讓我們來(lái)看看它內(nèi)部做了一些什么事情。
            以下是它內(nèi)部實(shí)現(xiàn)的一個(gè)偽代碼
            :

                CoCreateInstance(....)
                {
                .......
                IClassFactory *pClassFactory=NULL;
                CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
                pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
                pClassFactory->Release();
                ........
               }

            這段話的意思就是先得到類廠對(duì)象,再通過(guò)類廠創(chuàng)建組件從而得到IUnknown指針。繼續(xù)深入一步,看看CoGetClassObject的內(nèi)部偽碼:

               CoGetClassObject(.....)
               {
                //通過(guò)查注冊(cè)表CLSID_Object,得知組件DLL的位置、文件名
                //裝入DLL庫(kù)
                //使用函數(shù)GetProcAddress(...)得到DLL庫(kù)中函數(shù)DllGetClassObject的函數(shù)指針。
                //調(diào)用DllGetClassObject
               }
            DllGetClassObject是干什么的,它是用來(lái)獲得類廠對(duì)象的。只有先得到類廠才能去創(chuàng)建組件.
                下面是DllGetClassObject的偽碼:
                DllGetClassObject(...)
                {
                ......
                CFactory* pFactory= new CFactory; //類廠對(duì)象
                pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
                //查詢IClassFactory指針
                pFactory->Release();
                ......
                }
                CoGetClassObject的流程已經(jīng)到此為止,現(xiàn)在返回CoCreateInstance,看看CreateInstance的偽碼:
                CFactory::CreateInstance(.....)
                {
                ...........
                CObject *pObject = new CObject; //組件對(duì)象
                pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
                pObject->Release();
                ...........
                }


            四,COM的調(diào)用方法
            對(duì)上面手動(dòng)創(chuàng)建的COM的調(diào)用實(shí)例:

            int main()
            {
                
            // initialize the COM runtime
                cout 
            << "Initialize the COM runtime";
                CoInitialize(
            NULL);
                cout 
            << "success." << endl;

                
            // declare variables
                HRESULT hr;
                IClassFactory
            * pICF = NULL;
                ICreateMyCar
            *  pICreateMyCar = NULL;
                IEngine
            *       pIEngine = NULL;
                IStats
            *        pIStats = NULL;

                cout 
            << endl << "Get the class factory interface for the Car class";
                hr 
            = CoGetClassObject(CLSID_MyCar,CLSCTX_LOCAL_SERVER,NULL,IID_IClassFactory,(void**)&pICF);
                
            if ( FAILED(hr) )
                {
                    cout
            <<"fail";
                    
            exit(1);
                }
                
            else cout << "success." << endl;
                
                cout 
            << "Create the Car object and get back the ICreateMyCar interface";
                hr 
            = pICF->CreateInstance(NULL,IID_ICreateMyCar,(void**)&pICreateMyCar);
                
            if ( FAILED(hr) )
                {
                    
            //ShowErrorMessage("CoGetClassObject()",hr);
                    
            exit(1);
                }
                
            else cout << "success." << endl;
                
                
            // set parameters on the car
                cout 
            << endl << "Set different parameters on the car";
                pICreateMyCar
            ->SetMaxSpeed(30);
                BSTR carName 
            = SysAllocString(OLESTR("COMCar?!"));
                pICreateMyCar
            ->SetPetName(carName);
                SysFreeString(carName);
                cout 
            << "success." << endl;

                cout 
            << endl << "Query the IStats interface";
                pICreateMyCar
            ->QueryInterface(IID_IStats,(void**)&pIStats);
                cout 
            << "success." << endl;

                cout 
            << endl << "Use the IStats interface to display the status of the car:" << endl;
                pIStats
            ->DisplayStats();

                cout 
            << endl << "Query the IEngine interface";
                pICreateMyCar
            ->QueryInterface(IID_IEngine,(void**)&pIEngine);
                cout 
            << "success." << endl;

                cout 
            << endl << "Start to use the engine" << endl;
                
            int curSp = 0;
                
            int maxSp = 0;
                pIEngine
            ->GetMaxSpeed(&maxSp);
                
            do
                {
                    pIEngine
            ->SpeedUp();
                    pIEngine
            ->GetCurSpeed(&curSp);
                    cout 
            << "current speed is: " << curSp << endl;
                } 
            while (curSp <= maxSp);

                cout 
            << endl << "Report status again: " << endl;
                pIStats
            ->DisplayStats();

                
            if ( pICF )         pICF->Release();
                
            if ( pICreateMyCar) pICreateMyCar->Release();
                
            if ( pIStats )      pIStats->Release();
                
            if ( pIEngine )     pIEngine->Release();

                cout 
            << endl << "Close the COM runtime";
                CoUninitialize();
                cout 
            << "success." << endl;

                return 
            0;
            }


            方法一:向上面的調(diào)用,通過(guò)包含#include "../CarLocalServer/CarLocalServerTypeInfo_h.h"和#include "../CarLocalServer/CarLocalServerTypeInfo_i.c"

            方法二:使用#import導(dǎo)入tlb

            可以使用: CComBSTR ,CComPtr<> 和 CComQIPtr<> 等來(lái)簡(jiǎn)化調(diào)用。

            五,總結(jié)
            COM比一般的DLL有很多的優(yōu)點(diǎn),COM沒(méi)有重名問(wèn)題,因?yàn)楦静皇峭ㄟ^(guò)函數(shù)名來(lái)調(diào)用函數(shù),而是通過(guò)虛函數(shù)表,自然也不會(huì)有函數(shù)名修飾的問(wèn)題。路徑問(wèn)題也不復(fù)存在,因?yàn)槭峭ㄟ^(guò)查注冊(cè)表來(lái)找組件的,放在什么地方都可以,即使在別的機(jī)器上也可以。也不用考慮和EXE的依賴關(guān)系了,它們二者之間是松散的結(jié)合在一起,可以輕松的換上組件的一個(gè)新版本,而應(yīng)用程序混然不覺(jué)。

            但是COM仍然是有問(wèn)題的,比如說(shuō)版本控制的問(wèn)題,.NET將逐步代替COM的使用。

            六,參考
            1)OLE/COM/COM+/DCOM/ActiveX/ActiveX contorl ( 概念)
            2)用VC進(jìn)行COM編程所必須掌握的理論知識(shí)
            3)COM編程入門(1)
            4)COM編程入門(2)
            5)c++中使用com的方法

            posted on 2007-05-28 19:45 夢(mèng)在天涯 閱讀(9101) 評(píng)論(5)  編輯 收藏 引用 所屬分類: CPlusPlus

            評(píng)論

            # re: C++ COM 2007-05-28 21:39 夢(mèng)在天涯

            以上的手動(dòng)創(chuàng)建COM實(shí)例,還有一定的問(wèn)題,有那位高手愿意指點(diǎn),使我改正,共同進(jìn)步,還有COM的其他的調(diào)用方法,還有文章中的其他的問(wèn)題,請(qǐng)幫忙指出,我將非常的感謝!

            勇于共享!  回復(fù)  更多評(píng)論   

            # re: C++ COM 2007-05-28 22:32 萬(wàn)連文

            其實(shí)代碼邏輯可以用C++抽象機(jī)制+設(shè)計(jì)模式去實(shí)現(xiàn),而com的重點(diǎn)在夸語(yǔ)言平臺(tái),把它作為一種interop手段是再好不過(guò)。在開(kāi)發(fā)后期如果設(shè)計(jì)得當(dāng),用com做一層wrapper是很容易的事情。  回復(fù)  更多評(píng)論   

            # re: C++ COM 2007-05-29 00:15 meet-dream

            其實(shí)增加一層wrapper也是一件很ugly的事,如果效率是可以接受的,建議直接在對(duì)象模型上去實(shí)現(xiàn)。在wrapper同樣會(huì)把效率降的更低。  回復(fù)  更多評(píng)論   

            # re: C++ COM 2007-06-22 12:26 .net編程

            學(xué)習(xí)中  回復(fù)  更多評(píng)論   

            # re: C++ COM 2014-02-10 15:49 sunnyes2008

            MARK  回復(fù)  更多評(píng)論   

            公告

            EMail:itech001#126.com

            導(dǎo)航

            統(tǒng)計(jì)

            • 隨筆 - 461
            • 文章 - 4
            • 評(píng)論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1804603
            • 排名 - 5

            最新評(píng)論

            閱讀排行榜

            久久er国产精品免费观看8| 精品久久久久久亚洲| 久久国产福利免费| 嫩草影院久久99| 国产成人精品免费久久久久| 亚洲AV无码久久精品色欲| 国产精品久久久久a影院| 亚洲人AV永久一区二区三区久久 | 久久精品国产亚洲欧美| 97久久超碰成人精品网站| 久久久免费精品re6| 99999久久久久久亚洲| 麻豆精品久久精品色综合| 久久精品国产91久久综合麻豆自制 | 亚洲中文字幕无码一久久区| 99蜜桃臀久久久欧美精品网站 | 久久青青草原国产精品免费| 国产精品久久久久久福利69堂| 久久发布国产伦子伦精品 | 久久精品无码一区二区三区免费| 99久久免费国产精品| 久久黄视频| 久久综合亚洲色HEZYO社区| 婷婷久久久亚洲欧洲日产国码AV| 精品久久久久久无码专区不卡| 91精品久久久久久无码| 久久精品国产精品亚洲艾草网美妙| 久久无码一区二区三区少妇| 久久天天躁狠狠躁夜夜不卡| 狼狼综合久久久久综合网| 国产精品视频久久久| 久久精品国产国产精品四凭| 怡红院日本一道日本久久| 色综合久久久久综合99| 狠狠色狠狠色综合久久| 成人久久精品一区二区三区| 久久99精品九九九久久婷婷| 久久婷婷国产剧情内射白浆| 国内精品久久久久久野外| 久久婷婷五月综合成人D啪| 97精品依人久久久大香线蕉97 |