0

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

次に、テストコードを段階的に実行しています。tli ファイルに移動すると、次の内容が表示されます

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

pSource はまったく問題なく、データが含まれているメモリ領域を指しています。しかし、さらに進んで (デバッガーを使用してサービスに接続している)、サービスの関数 SetBytes を使用している場合、この配列の 1 バイトのみがメモリ領域に含まれ、このポインターは別のアドレスを指します。

私はdllを介してサーバーを実装しようとしました(regsvr32 [dllname]を使用してシステムに登録されています)。この場合、ポインターは完全に問題なく、1バイトだけでなくすべての長さが渡されました。

私は COM テクノロジに不慣れで、どこが間違っているのか疑問に思っています。

4

2 に答える 2

0

SAFEARRAYCOM でバイト配列を渡すには、a を使用する必要があります。

于 2013-03-07T23:29:01.030 に答える
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;
    }
}
于 2013-03-07T23:31:31.620 に答える