读书人

请教SAFEARRAY该如何用

发布时间: 2012-03-22 17:43:57 作者: rapoo

请问SAFEARRAY该怎么用?
实在是搞不定了
我在ATL里创建SAFEARRAY把自定义的结构体放进去,如下:

C/C++ code
typedef struct _t{    int i;}MyData;STDMETHODIMP CMyDataset::GetLongs3(VARIANT *parray){    USES_CONVERSION;       char   buffer[20];       HRESULT   hr=   S_OK;       //   Create   SafeArray   of   VARIANT   BSTRs       SAFEARRAY   *pSA;       SAFEARRAYBOUND   aDim[1];       aDim[0].lLbound=   0;       aDim[0].cElements=   3;       pSA=   SafeArrayCreate(VT_VARIANT, 1,aDim);      if   (pSA   !=   NULL)         {           _variant_t   vOut;           for   (long   l=   aDim[0].lLbound;   l< (aDim[0].cElements   +   aDim[0].lLbound);   l++)             {                 MyData *pData = new DailyData;            pData->i = l;            if   (hr=   SafeArrayPutElement(pSA,   &l,   pData))                 {                   SafeArrayDestroy(pSA);   //   does   a   deep   destroy                   return   hr;               }           }       }       V_VT(parray)=   VT_ARRAY   |   VT_VARIANT;         V_ARRAY(parray)=   pSA;         return   S_OK;   }

本来打算在VB里读出这个自定义结构,结果现在用vc些客户端也读不出来,不知道为什么啊
C/C++ code
            VARIANT varResult;                        IDataset->GetLongs3(&varResult);            //if (varResult.vt == VT_ARRAY)            {                MyData * pData = NULL;                MyData HUGEP *pbstr;                long LBound, HBound;                SafeArrayGetLBound(varResult.parray, 1, &LBound);                SafeArrayGetUBound(varResult.parray, 1, &HBound);                SafeArrayAccessData(varResult.parray, (void HUGEP* FAR*)&pData);                MyData data;                for(long index=LBound;index<=HBound;index++)                         {                               ::SafeArrayGetElement(varResult.parray,&index, &data);                                           MyData *psinfo = &pData[index];                                //show info.....                    printf("%d\n", psinfo->i);                }}

其中LBound,HBound都对啊,pData的pvData也对,就是不知道数据为什么不对,而且还是乱码....

[解决办法]
ok,自定义类型如果是比较简单的类型,可以通过LONG,LONGLONG等等来强制转换
如果比较复杂例如
struct st
{
int a;
string b;
};
那么就需要你把这个类型注册到com里面,让外界例如VB程序可识别

步骤如下:
1.COM里面添加一个“ATL简单对象”,假设叫MyData,
向导生成的对象将是 IMyData, CLSID名为CLSID_MyData
2.为IMyData添加2个属性,一个叫a,一个叫b,赋予get,put属性,自己书写get,put的代码
3.书写COM查询函数如下:
C/C++ code
struct st{int a;string b;};void StToSafeArray(st * pBuf,int BufLen,VARIANT * vt){   SAFEARRAY * psa;    SAFEARRAYBOUND rgsabound[1];    rgsabound[0].lLbound = 0;    rgsabound[0].cElements = BufLen;    psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);    for(LONG i=0;i<BufLen;i++)    {        IMyData * tmp;        ::CoCreateInstance(CLSID_MyData,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&tmp);        tmp->put_a(pBuf[i].a);                tmp->put_b(pBuf[i].b);        CComVariant v(tmp);        SafeArrayPutElement(psa,&i,&v);    }    vt->vt = VT_ARRAY|VT_VARIANT;    vt->parray = psa; }STDMETHODIMP CTestUdtForm::Query(VARIANT* data){    // TODO: 在此添加实现代码    int len = 100;    st * d = new st[len];    for(int i=0;i<len;i++)    {      d[i].a = i;          d[i].b = "hello world";    }    StToSafeArray(d,len,data);    return S_OK;} 

读书人网 >VC/MFC

热点推荐