COM服务器作为windows服务,不能将数组作为函数参数传递 [英] COM server as windows service, cannot pass array as function argument

查看:130
本文介绍了COM服务器作为windows服务,不能将数组作为函数参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

此方法在IDL文件中声明:

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


$ b b

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

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绝对可以指向包含我的数据的内存区域。但是当我进一步(我附加到服务与调试器)和我在服务的函数SetBytes,只有一个字节从这个数组包含在内存区域和这个指针指向不同的地址。

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.

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

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.

我是COM技术的新手,想知道我错了。

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

推荐答案

你可能会把你的BYTE数组包装成一个SAFEARRAY。

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

这篇关于COM服务器作为windows服务,不能将数组作为函数参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆