- 注册时间
- 2021-4-16
- 最后登录
- 2024-3-30
- 在线时间
- 2 小时
编程入门
- 龙马币
- 32
|
在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;
- }
复制代码
|
|