请问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;}