您的位置:首页 > 其它

COM组件,字符串数组的传递

2017-02-20 13:42 197 查看
    前阵子做作业,需要用到COM。在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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: