- 注册时间
 - 2021-4-16
 
- 最后登录
 - 2024-9-9
 
- 在线时间
 - 2 小时
 
 
 
 
 
编程入门 
  
	- 龙马币
 - 234 
 
 
 
 
 | 
 
 
在ATL下开发简单的COM组件很简单,唯一的难点在于复杂参数的传递。比如说字符串数组,需要学习SAFFARRAY,bstr以及VARIANT的用法。 
 
下面贴出代码,展示一个字符串数组如何传递。 
 
在COM组件的方法里面: 
-   STDMETHODIMP CwordCountService::analyzeTheWordFile(BSTR filename, VARIANT* wordsSafearray, VARIANT* frequencySafearray)
 
 - {
 
 -         // TODO: 在此添加实现代码
 
 -         MYWORD **wordArray;
 
 -         int wordCount;
 
 -         char *cFilename = _com_util::ConvertBSTRToString(filename);
 
 -         //调用analyzeTxtWordFile函数对指定文档进行统计分析
 
 -         analyzeTxtWordFile(cFilename, &wordArray, &wordCount);
 
 -         delete cFilename;
 
 -         cFilename = nullptr;
 
 -  
 
 -         //把统计到的结果,存放到安全数组里面
 
 -         VARIANT var1, var2;
 
 -         VariantInit(&var1);
 
 -         VariantInit(&var2);
 
 -         var1.vt = VT_BSTR;
 
 -         var2.vt = VT_INT;
 
 -         SAFEARRAY *pArray1, *pArray2;
 
 -         pArray1 = SafeArrayCreateVector(VT_VARIANT, 0, wordCount);
 
 -         pArray2 = SafeArrayCreateVector(VT_VARIANT, 0, wordCount);
 
 -         for (long i = 0; i < wordCount; i++)
 
 -         {
 
 -                 var1.bstrVal = _com_util::ConvertStringToBSTR(wordArray[i]->MYWORD);
 
 -                 var2.intVal = wordArray[i]->count;
 
 -                 SafeArrayPutElement(pArray1, &i, &var1);
 
 -                 SafeArrayPutElement(pArray2, &i, &var2);
 
 -                 free(wordArray[i]);
 
 -         }
 
 -         free(wordArray);
 
 -  
 
 -         VariantClear(&var1);
 
 -         VariantClear(&var2);
 
 -         wordsSafearray->vt = VT_ARRAY | VT_VARIANT;
 
 -         frequencySafearray->vt = VT_ARRAY | VT_VARIANT;
 
 -         wordsSafearray->parray = pArray1;
 
 -         frequencySafearray->parray = pArray2;
 
 -         return S_OK;
 
 - }
 
  复制代码 
 
调用COM组件的C++代码: 
- #include <atlbase.h>  
 
 - #import "D:\wordCountComponent.dll" no_namespace 
 
 -  
 
 - int main()
 
 - {
 
 -         //根据接口的clsid来初始化com组件
 
 -         CoInitialize(NULL);
 
 -         CLSID clsid;
 
 -         HRESULT hr = CLSIDFromString(OLESTR("{40F2E186-5636-4F0D-87AB-DF351B41D133}"), &clsid);
 
 -  
 
 -         //用智能指针去获取接口指针
 
 -         CComPtr<IwordCountService> wordCountServicePtr;
 
 -         hr = wordCountServicePtr.CoCreateInstance(clsid);
 
 -         if (NOERROR != hr)
 
 -         {
 
 -                 printf("初始化com失败!\n");
 
 -                 return -1;
 
 -         }
 
 -  
 
 -         VARIANT var1, var2;
 
 -         VariantInit(&var1);
 
 -         VariantInit(&var2);
 
 -         SAFEARRAY *pArray1, *pArray2;
 
 -  
 
 -         BSTR fileName = _com_util::ConvertStringToBSTR("d:/Romeo and Juliet.txt");
 
 -         //调用analyzeTheWordFile函数分析文件,分析得到的结果存放在var1, var2的安全数组中
 
 -         wordCountServicePtr->analyzeTheWordFile(fileName, &var1, &var2);
 
 -         ::SysFreeString(fileName);
 
 -         BSTR fileName2 = _com_util::ConvertStringToBSTR("d:/log.txt");
 
 -         //分析完之后,可以利用得到的结果,调用createTxtLogFile生成统计文件
 
 -         wordCountServicePtr->createTxtLogFile(fileName2, var1, var2);
 
 -         ::SysFreeString(fileName2);
 
 -  
 
 -         //下列代码展示了如何把数据从安全数组里面读取出来,并且保证内存不泄露
 
 -         pArray1 = var1.parray;
 
 -         pArray2 = var2.parray;
 
 -  
 
 -         //获取安全数组的上下边界以及长度
 
 -         long plLowBound, plUpperBound;
 
 -         SafeArrayGetLBound(pArray1, 1, &plLowBound);
 
 -         SafeArrayGetUBound(pArray1, 1, &plUpperBound);
 
 -         int wordCount = plUpperBound - plLowBound + 1;
 
 -         char **wordArray = new char*[wordCount];
 
 -         int *frequencyArray = new int[wordCount];
 
 -         VARIANT temp1, temp2;
 
 -         VariantInit(&temp1);
 
 -         VariantInit(&temp2);
 
 -         for (long i = plLowBound; i <= plUpperBound; i++)
 
 -         {
 
 -                 ::SafeArrayGetElement(pArray1, &i, &temp1);
 
 -                 ::SafeArrayGetElement(pArray2, &i, &temp2);
 
 -                 wordArray[i] = _com_util::ConvertBSTRToString(temp1.bstrVal);
 
 -                 frequencyArray[i] = temp2.intVal;
 
 -         }
 
 -  
 
 -         //把从安全数组读取出来的数据打印到屏幕上
 
 -         for (long i = plLowBound; i <= plUpperBound; i++)
 
 -         {
 
 -                 printf("%s %d\n", wordArray[i], frequencyArray[i]);
 
 -         }
 
 -  
 
 -         //调用searchWord搜索指定单词出现频率
 
 -         BSTR theWord = _com_util::ConvertStringToBSTR("the");
 
 -         long frequency = 0;
 
 -         wordCountServicePtr->searchWord(theWord, var1, var2, &frequency);
 
 -         ::SysFreeString(theWord);
 
 -         printf("所搜索的单词在文本出现频数为%ld次\n", frequency);
 
 -  
 
 -         for (long i = plLowBound; i <= plUpperBound; i++)
 
 -         {
 
 -                 ::SafeArrayGetElement(pArray1, &i, &temp1);
 
 -                 //释放掉安全数组里面的bstr内存
 
 -                 ::SysFreeString(temp1.bstrVal);
 
 -                 //释放掉字符串内存
 
 -                 delete wordArray[i];
 
 -         }
 
 -         delete[] wordArray;
 
 -         delete[] frequencyArray;
 
 -  
 
 -         //安全数组使用完毕之后记得销毁
 
 -         SafeArrayDestroy(pArray1);
 
 -         SafeArrayDestroy(pArray2);
 
 -         //释放智能指针
 
 -         wordCountServicePtr.Release();
 
 -         //卸载com组件
 
 -         CoUninitialize();
 
 -         return 0;
 
 - }
 
  复制代码 
 
 |   
 
 
 
 |