COM server as windows service, cannot pass array as function argument

橙三吉。 提交于 2019-12-12 02:24:52

问题


I'm implementing COM server (using ATL) as Windows service. I have the following method defined in service header:

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

This method is declared in the IDL file:

[
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);
};

I'm calling it from my test application like this:

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]);

I'm registering service by performing:

MyService.exe /regserver
MyService.exe -service

Then I'm executing test code step by step. When I'm going to tli file where we can see the following

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

pSource is absolutely ok and points to the area of memory where my data is contained. But when I'm going further (I'm attached to the service with debugger) and I'm in service's function SetBytes, only one byte from this array is contained in memory area and this pointer points to the different address.

I have tried implementing server via dll (it's registered in the system with regsvr32 [dllname]) and the pointer was absolutely ok in it in this case and all the length was passed, not only one byte.

I'm new to COM technology and wondering where I am wrong.


回答1:


you could maybe wrap your BYTE array it into a 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;
    }
}



回答2:


You need to use a SAFEARRAY to pass byte arrays around in COM.



来源:https://stackoverflow.com/questions/15282328/com-server-as-windows-service-cannot-pass-array-as-function-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!