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

    前阵子做作业,需要用到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;
}


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值