diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 20:42:25 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 20:42:25 +0000 |
commit | 56a5107804d263d258858af7c3905d3cd5c5957e (patch) | |
tree | 42030f41b1b7ce87a16a0c346e928bbc0042d101 /remoting/base/dispatch_win.h | |
parent | 6264f9d8a57df8a3cefae27a00b070113f0de67d (diff) | |
download | chromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.zip chromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.tar.gz chromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.tar.bz2 |
Adding support of [in] [out] parameters to remoting::dispatch::Invoke().
BUG=131498
Review URL: https://chromiumcodereview.appspot.com/10532143
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143443 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/dispatch_win.h')
-rw-r--r-- | remoting/base/dispatch_win.h | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/remoting/base/dispatch_win.h b/remoting/base/dispatch_win.h index 1d12a70..aa20710 100644 --- a/remoting/base/dispatch_win.h +++ b/remoting/base/dispatch_win.h @@ -23,7 +23,7 @@ namespace internal { // A helper wrapper for |VARIANTARG| that is used to pass parameters to and from // IDispatch::Invoke(). The latter accepts parameters as an array of -// |VARIANTARG| structures. The calling convention is: +// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is: // - [in] parameters are initialized and freed if needed by the caller. // - [out] parameters are initialized by IDispatch::Invoke(). It is up to // the caller to free leakable variants (such as VT_DISPATCH). @@ -33,11 +33,9 @@ namespace internal { // // Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that // the resources allocated during the call will be properly freed. It also -// provides wraping methods that convert between C++ types and VARIANTs. -// The current convention is: -// - constant references are considered input parameters. -// - pointers to non-constant objects are considered output parameters. -// - [in] [out] parameters are not supported. +// provides wrapping methods that convert between C++ types and VARIANTs. +// At the moment the only supported parameter type is |VARIANT| (or +// |VARIANTARG|). // // It must be possible to cast a pointer to an array of |ScopedVariantArg| to // a pointer to an array of |VARIANTARG| structures. @@ -55,11 +53,20 @@ class ScopedVariantArg : public VARIANTARG { // that they can be passed to IDispatch::Invoke. HRESULT Wrap(const VARIANT& param) { + DCHECK(vt == VT_EMPTY); return VariantCopy(this, ¶m); } HRESULT Wrap(VARIANT* const & param) { - // Do nothing for an [out] parameter. + DCHECK(vt == VT_EMPTY); + + // Make the input value of an [in] [out] parameter visible to + // IDispatch::Invoke(). + // + // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In + // other words the caller is always responsible for initializing and freeing + // [out] and [in] [out] parameters. + Swap(param); return S_OK; } @@ -71,11 +78,19 @@ class ScopedVariantArg : public VARIANTARG { } void Unwrap(VARIANT* const & param_out) { - *param_out = *this; - vt = VT_EMPTY; + // Return the output value of an [in] [out] parameter to the caller. + Swap(param_out); } private: + // Exchanges the value (and ownership) of the passed VARIANT with the one + // wrapped by |ScopedVariantArg|. + void Swap(VARIANT* other) { + VARIANT temp = *other; + *other = *this; + *static_cast<VARIANTARG*>(this) = temp; + } + DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg); }; @@ -89,8 +104,14 @@ COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG), // calling the desired method by its ID and implements logic for passing // a variable number of in/out parameters to the called method. // +// The calling convention is: +// - [in] parameters are passsed as a constant reference or by value. +// - [out] and [in] [out] parameters are passed by pointer. The pointed value +// is overwritten when the function returns. The pointed-to value must +// be initialized before the call, and will be replaced when it returns. +// [out] parameters may be initialized to VT_EMPTY. +// // Current limitations: -// - in_out parameters are not supported. // - more than 7 parameters are not supported. // - the method ID cannot be cached and reused. // - VARIANT is the only supported parameter type at the moment. @@ -122,8 +143,9 @@ HRESULT Invoke(IDispatch* object, // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -164,8 +186,9 @@ HRESULT Invoke(IDispatch* object, disp_args[1 - 1].Unwrap(p1); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -211,8 +234,9 @@ HRESULT Invoke(IDispatch* object, disp_args[2 - 2].Unwrap(p2); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -263,8 +287,9 @@ HRESULT Invoke(IDispatch* object, disp_args[3 - 3].Unwrap(p3); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -320,8 +345,9 @@ HRESULT Invoke(IDispatch* object, disp_args[4 - 4].Unwrap(p4); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -382,8 +408,9 @@ HRESULT Invoke(IDispatch* object, disp_args[5 - 5].Unwrap(p5); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -450,8 +477,9 @@ HRESULT Invoke(IDispatch* object, disp_args[6 - 6].Unwrap(p6); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } @@ -523,8 +551,9 @@ HRESULT Invoke(IDispatch* object, disp_args[7 - 7].Unwrap(p7); // Unwrap the return value. - if (result_out != NULL) + if (result_out != NULL) { result.Unwrap(result_out); + } return S_OK; } |