本文共 3928 字,大约阅读时间需要 13 分钟。
本不想写这篇文章,因为在COM中使用数组无非是个SAFEARRAY的使用问题,查查MSDN就可以了。 但是看到有很多人问这个问题,觉得给大家一个范例模仿更好一些,大家看MSDN也不致那么辛苦了。 代码中给了两种数组的用法,一种是字符串数组,另一种是自定义数据结构数组。一、字符串数组
关键代码:组件方:STDMETHODIMP CTestArray::Show1(SAFEARRAY *pSa){ // TODO: Add your implementation code hereif (pSa !=NULL){ VARTYPE vt;SafeArrayGetVartype(pSa, &vt);//判别数组元素类型if (vt != VT_BSTR)return S_FALSE;long lLBound, lUBound;
BSTR *pBstr;char strText[1024]="", strTemp[100];SafeArrayGetLBound(pSa, 1, &lLBound);//一维数组下标SafeArrayGetUBound(pSa, 1, &lUBound);//一维数组上标SafeArrayAccessData(pSa, (void**)&pBstr);for (long i=lLBound; i<=lubound; i++) { wcstombs(strTemp, *(pBstr+i), 100); strcat(strText, strTemp); } SafeArrayUnaccessData(pSa); ::MessageBox(NULL, strText, "Use Array in COM DLL", MB_OK); return S_OK; } return S_FALSE; } 客户方: void CTestDlg::OnButton1() { USES_CONVERSION;//想用T2OLE就必须加上这一句
CoInitialize(NULL);
ITestArrayPtr ptr;
ptr.CreateInstance(__uuidof(TestArray));SAFEARRAYBOUND pSab[1];
pSab[0].lLbound = 0;pSab[0].cElements= 3;SAFEARRAY *pSa;pSa = SafeArrayCreate(VT_BSTR, 1, pSab);BSTR *pBstr;
SafeArrayAccessData(pSa, (void**)&pBstr);*(pBstr) = SysAllocString(T2OLE("BSTR1 "));//也可用A2W*(pBstr+1) = SysAllocString(T2OLE("BSTR2 "));*(pBstr+2) = SysAllocString(T2OLE("BSTR3 "));SafeArrayUnaccessData(pSa);ptr->Show1(pSa);
SafeArrayDestroy(pSa);
ptr.Release();
CoUninitialize();
}二、自定义数据结构数组
关键代码:组件方:STDMETHODIMP CTestArray::Show2(SAFEARRAY *pSa){ if (pSa !=NULL){ VARTYPE vt;SafeArrayGetVartype(pSa, &vt);//判别数组元素类型if (vt != VT_RECORD) //VT_RECORD型return S_FALSE;long lLBound, lUBound;
STUDENT *pStudent;char strText[4096]="", strTemp[100];SafeArrayGetLBound(pSa, 1, &lLBound);//一维数组下标SafeArrayGetUBound(pSa, 1, &lUBound);//一维数组上标SafeArrayAccessData(pSa, (void**)&pStudent);for (long i=lLBound; i<=lubound; i++)
{ wcstombs(strTemp, (*(pStudent+i)).name, 100); strcat(strText, "name=");strcat(strText, strTemp);strcat(strText, " /n"); sprintf(strTemp, "grade="%d/n"," (*(pStudent+i)).grade); strcat(strText, strTemp); if ((*(pStudent+i)).sex="=" 0) strcpy(strTemp, "male/n"); else strcpy(strTemp, "female/n"); strcat(strText, "sex=");strcat(strText, strTemp);if ((*(pStudent+i)).graduate)strcpy(strTemp, " true/n"); else strcpy(strTemp, "false/n"); strcat(strText, "graduate:"); strcat(strText, strTemp); strcat(strText, "/n"); } SafeArrayUnaccessData(pSa); ::MessageBox(NULL, strText, "Use Array in COM DLL", MB_OK); return S_OK; } return S_FALSE; } 客户方: void CTestDlg::OnButton2() { const GUID GUID_STUDENT="{0xF7D09422,0xB295,0x11d4,{0x98,0xDB,0x00,0x80,0xC8,0xF5,0xB2,0xE4}};" CoInitialize(NULL); ITypeInfo *pTypeInfo="NULL;" ITypeLib *pTypelib="NULL;" IRecordInfo *pRecInfo="NULL;" SAFEARRAY *psaStudent="NULL;" SAFEARRAYBOUND rgbounds="{" 4, 0 }; STUDENT *pStudentStruct="NULL;" ITestArrayPtr ptr; LoadRegTypeLib(LIBID_USEARRAYLib, 1, 0, GetUserDefaultLCID(), &pTypelib); pTypelib->GetTypeInfoOfGuid(GUID_STUDENT, &pTypeInfo);GetRecordInfoFromTypeInfo(pTypeInfo, &pRecInfo);pTypeInfo->Release();pTypelib->Release();//只有用VT_RECORD才能识别数据结构
psaStudent = SafeArrayCreateEx(VT_RECORD, 1, &rgbounds, pRecInfo);pRecInfo->Release();SafeArrayAccessData(psaStudent, (void**)(&pStudentStruct));
pStudentStruct[0].grade = 3;pStudentStruct[0].name = SysAllocString(L"Lostall");//用L更简单pStudentStruct[0].sex = male;pStudentStruct[0].graduate = true;pStudentStruct[1].grade = 8;pStudentStruct[1].name = SysAllocString(L"Nicesnower");pStudentStruct[1].sex = female;pStudentStruct[1].graduate = false;pStudentStruct[2].grade = 12;pStudentStruct[2].name = SysAllocString(L"Mike");pStudentStruct[2].sex = male;pStudentStruct[2].graduate = true;pStudentStruct[3].grade = 3;pStudentStruct[3].name = SysAllocString(L"Linda");pStudentStruct[3].sex = female;pStudentStruct[3].graduate = false;SafeArrayUnaccessData(psaStudent);ptr.CreateInstance(CLSID_TestArray);
ptr->Show2(psaStudent);ptr.Release();CoUninitialize();}转载地址:http://ioxqj.baihongyu.com/