我正在使用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);
};
我从我的测试应用程序中调用它:
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
然后我一步一步地执行测试代码。当我要提交文件时,我们可以看到以下内容
HRESULT _hr = raw_SetBytes(lenSource, pSource, &_result);
pSource绝对可以,并指向包含我的数据的内存区域。但是当我进一步(我使用调试器连接到服务)并且我在服务的函数SetBytes时,只有该数组中的一个字节包含在内存区域中,并且该指针指向不同的地址。
我尝试通过dll实现服务器(它在系统中使用regsvr32 [dllname]注册)并且在这种情况下指针绝对正常并且所有长度都被传递,而不仅仅是一个字节。
我是COM技术的新手,想知道我错在哪里。
答案 0 :(得分:0)
您需要使用SAFEARRAY
在COM中传递字节数组。
答案 1 :(得分:0)
你可以将你的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;
}
}