COM服务器作为Windows服务,不能传递数组作为函数参数

我正在实施COM服务器(使用ATL)作为Windows服务。 我在服务头中定义了以下方法:

STDMETHOD(SetBytes)(long lenSource, const BYTE* pSource, VARIANT_BOOL *pResult); 

这个方法在IDL文件中声明:

 [ object, uuid(351C5A5F-3EB8-4CC5-AB79-6DCD27C2F7E0), dual, pointer_default(unique) ] interface ISampleInterface: IUnknown { HRESULT SetBytes([in] long lenSource, [in,ref,size_is(lenSource)] const BYTE* pSource, [out,retval] VARIANT_BOOL *pResult); }; 

我从我的testing应用程序调用它像这样:

 CoInitialize(NULL); IUnknownPtr unknown_ptr; HRESULT hr = unknown_ptr.CreateInstance(__uuidof(MyLib::SampleManager)); if (FAILED(hr)) { ... }; MyLib::ISampleInterfacePtr sample_ptr; sample_ptr = unknown_ptr; // no check here, assume sample_ptr is not null VARIANT_BOOL function_result = VARIANT_FALSE; vector<uint8_t> flash_data(1000, 2); function_result = sample_ptr->SetBytes(flash_data.size(), &flash_data[0]); 

我正在通过执行以下操作注册服务:

 MyService.exe /regserver MyService.exe -service 

然后我一步一步地执行testing代码。 当我要去tli文件,我们可以看到以下内容

 HRESULT _hr = raw_SetBytes(lenSource, pSource, &_result); 

pSource绝对可以,并指向我的数据所在的内存区域。 但是,当我进一步(我用debugging器附加到服务),并且我在服务的函数SetBytes,只有一个字节从这个数组包含在内存区域,这个指针指向不同的地址。

我已经尝试过通过dll实现服务器(它在系统中用regsvr32 [dllname]注册),在这种情况下,指针是绝对可以的,并且所有的长度都被传递了,而不仅仅是一个字节。

我是新来的COM技术,想知道我错在哪里。

你也许可以把你的BYTE数组包装成一个SAFEARRAY。

  STDMETHODIMP MyClass::getVariantFromCharArray( char *inputCharArray, UINT inputCharArrayLength, VARIANT *outputVariant) { SAFEARRAYBOUND saBound; char *pData = NULL; saBound.cElements = inputCharArrayLength; saBound.lLbound = 0; VariantInit( outputVariant); (*outputVariant).vt = VT_UI1 | VT_ARRAY; (*outputVariant).parray = SafeArrayCreate( VT_UI1, 1, &saBound); if ( (*outputVariant).parray) { SafeArrayAccessData( (*outputVariant).parray, (void **)&pData); memcpy( pData, inputCharArray, inputCharArrayLength); SafeArrayUnaccessData( (*outputVariant).parray); return S_OK; } else { return E_OUTOFMEMORY; } } 

您需要使用SAFEARRAY来传递COM中的字节数组。