1. 问题背景
在《C#程序与COM服务程序传递数组和字符串的方式》一文中,我提供了数组的传递方式,是通过 atlsafe.h 中 CComSafeArray 模板类来实现的,但是在实际开发过程中发现,直接使用其自身提供的随机数据访问函数进行数据操作速度较慢,在大量传输数据时运行时间不可接受,所以本文记录一种高效传输方式。
1 STDMETHODIMP_(HRESULT __stdcall) CSimple::GetSourceDataInByte(SAFEARRAY** arr) 2 { 3 CComSafeArray<BYTE>* sfArrObj = new CComSafeArray<BYTE>; 4 // 这里 _sourceData 是 CSimple 中的源数据成员,类型为 void* 5 BYTE* srcData = static_cast<BYTE*>(_sourceData); 6 // 调用 Create() 为 sfArrObj 内数据分配内存空间;_srcDataLen 是源数据个数,类型为 ULONG 7 sfArrObj->Create(_srcDataLen); 8 for (ULONG i = 0; i < _srcDataLen; ++i) { 9 sfArrObj->SetAt(i, *(srcData + i)); 10 } 11 *arr = sfArrObj->Detach(); 12 delete sfArrObj; 13 sfArrObj = NULL; 14 return S_OK; 15 }
这个方法实现中,使用循环赋值的方式对 sfArrObj 中的数据块赋值,实测上亿数据量时运行时间在20秒以上。
2. 解决办法
考虑通过内存拷贝方式进行传输,需要用到标准库中的 memcpy() 函数。
1 STDMETHODIMP_(HRESULT __stdcall) CSimple::GetSourceDataInByte(SAFEARRAY** arr) 2 { 3 CComSafeArray<BYTE>* sfArrObj = new CComSafeArray<BYTE>; 4 sfArrObj->Create(_srcDataLen); 5 SAFEARRAY* safeArr = sfArrObj->Detach(); 6 memcpy(_safeArr->pvData, _sourceData, _srcDataLen * sizeof(BYTE)); 7 sfArrObj->Attach(safeArr); 8 *arr = sfArrObj->Detach(); 9 delete sfArrObj; 10 sfArrObj = NULL; 11 safeArr = NULL; 12 return S_OK; 13 }
通过这种方式传输亿级数据仅需3秒左右。
标签:CComSafeArray,arr,服务项目,数据,传输方式,sfArrObj,srcDataLen,safeArr,COM From: https://www.cnblogs.com/eternalmoonbeam/p/17814458.html