在用C++和ADO写数据库程序时,我习惯这样:CreateInstance(_T("ADODB.Connection"));现在出现问题了,Windows 2000系统中,虽然各种SQL代码调用返回信息都成功了,但是却没有正确执行SQL代码,后来改成CreateInstance(__uuidof(Connection))就好了,以下是CreateInstance的声明:
HRESULT CreateInstance(
   const CLSID& rclsid,
   IUnknown* pOuter=NULL,
   DWORD dwClsContext = CLSCTX_ALL 
) throw( );
HRESULT CreateInstance(
   LPCWSTR clsidString,
   IUnknown* pOuter=NULL,
   DWORD dwClsContext = CLSCTX_ALL 
) throw( );
HRESULT CreateInstance(
   LPCSTR clsidStringA,
   IUnknown* pOuter=NULL,
   DWORD dwClsContext = CLSCTX_ALL 
) throw( );
第一个参数都是CLSID,但是为什么我在Windows XP下传递非CLSID的_T("ADODB.Connection")也能成功呢??

解决方案 »

  1.   

    第一种是通过名字创建对象,可能会出现冲突.
    第二是通过uuid创建对象,这个uuid是唯一的.
    两种都是符合COM规范的.像JS都是使用第一种方式创建COM对象的
      

  2.   

    COM本质论上的一段原文除了用CLSID来命名实现之外,COM也支持文本方式的别称,被称为programmaticID
    或者ProgID。ProgID采用库名.类名.版本的形式,而且,与CLSID不同的是,我们只是为
    了方便而要求ProgID是唯一的。通过COM API函数CLSIDFromProgID和
    ProgIDFromCLSID,客户可以在ProgID和CLSID两者之间进行转换,这两个函数的原形如
    下:
    HRESULT CLSIDFromProgID([in,string]LPCOLESTR lpszProgID,[out] LPCLSID pclsid);
    HRESULT ProgIDFromCLSID([in]REFCLSID clsid,[out,string]LPOLESTaR* lplpszProgID);
    为了把一个ProgID转换为CLSID,我们只需简单的调用CLSIDFromProgID:
    HRESULT GetCGorillaCLSID(CLSID& rclsid){
    const OLECHAR wszProgID[] = OLESTR("Apes.Gorilla.l");
    return CLSIDFromProgID(wszProgID,&rclsid);
    }
      

  3.   

    因为你用的是第二或第三个版本,LPCWSTR   clsidString,或 LPCSTR   clsidStringA,当定义了_UNICODE时, _T( "ADODB.Connection ")中的_T就会将字符串转成wchar_t,见wchar_t定义( typedef unsigned short wchar_t;),然后就转换成LPCWSTR。如果无定义_UNICODE就用LPCSTR的版本。
      

  4.   

    当然有区别啊,第二种是以唯一的uuid(也叫CLSID)来获取,就像使用你的身份证来确定你这个人一样,而第一种是以这个COM类的名来获取,就可能重名,或无法找到这个名,导致无法再找到对应的UUID(CLSID),就好像用张三来找你一样,有几百个叫张三的,系统就不知道哪个是你了,或者你明明有身份证,但姓名没有登记正确,也就找不到你了.因此第二种最好的方法,不会出错.他用的就是相当于数据库表中的主键一样.唯一值!