Re: Behavior of out parameters and dependencies

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Laurents C. R. Meyer (Meyer_at_discussions.microsoft.com)
Date: 01/20/05

  • Next message: Laurents C. R. Meyer: "Re: CoInitialize fails with E_ACCESSDENIED after upgrade to XP SP2"
    Date: Thu, 20 Jan 2005 12:49:03 -0800
    
    

    Thanks a lot. This will save some bugs later in the project.
    In most cases it will be ok to just declare the pointers as ref, but in
    scenarios it can be usefull to pass null parameters which depends on each
    other, this seems to be the perfect solution. In my case I will do my stuff
    in the ..._Stub method.

    Thanks.
    - Laurents C. R. Meyer

    "Alexander Nickolov" wrote:

    > This is one of the finer points of marshaling. You need the [local]
    > and [call_as] atributes here:
    >
    > [pointer_default(unique), ...]
    > interface IFoo : IUnknown
    > {
    > [local]
    > HRESULT GetData( DWORD* pdwSize, BYTE** ppBuffer );
    > [call_as(GetData)]
    > HRESULT RemGetData( [out]DWORD* pdwSize, [out, size_is(
    > ,*pdwSize)]BYTE** ppBuffer );
    > };
    >
    > Then you need to write a small C file to link with the rest of the
    > proxy/stub code that does the conversion from the local method
    > into the remote method at the proxy, and back at the stub. Your
    > clients always call the local method, and that's what you implement
    > at the server. However, it's always the remote method that travels
    > on the wire. Of course, you need to modify the proxy/stub DLL
    > project to compile and link your file as well.
    >
    > HRESULT WINAPI IFoo_GetData_Proxy(IFoo* pThis, DWORD* pdwSize, BYTE**
    > ppBuffer)
    > {
    > if (IsBadWritePtr(pdwSize, sizeof(DWORD*)) || IsBadWritePtr(ppBuffer,
    > sizeof(BYTE**))) {
    > return S_FALSE;
    > }
    > return IFoo_RemGetData_Proxy(pThis, pdwSize, ppBuffer);
    > }
    >
    > HRESULT WINAPI IFoo_RemGetData_Stub(IFoo* pThis, DWORD* pdwSize, BYTE**
    > ppBuffer)
    > {
    > return pThis->lpVtbl->GetData(pThis, pdwSize, ppBuffer);
    > }
    >
    > Note the docs for [call_as] is wrong on numerous points. The
    > needed prototypes are declared in the header file produced
    > by MIDL.
    >
    > --
    > =====================================
    > Alexander Nickolov
    > Microsoft MVP [VC], MCSD
    > email: agnickolov@mvps.org
    > MVP VC FAQ: http://www.mvps.org/vcfaq
    > =====================================
    >
    > "Laurents C. R. Meyer" <Laurents C. R. Meyer@discussions.microsoft.com>
    > wrote in message news:CFE5270F-EAC9-433A-A95F-13C4C7ABBC70@microsoft.com...
    > > Hoi!
    > > I am currently thinking about an interesting exception in the COM usage
    > > and
    > > would like to hear if somebody knows about the behavior.
    > >
    > > Let's say there is Some Interface called IFoo. This interface offers one
    > > method called GetData. Because the caller does not know how large the
    > > buffer
    > > has to be, it is allocated by GetData using CoTaskMemAlloc. The user has
    > > the
    > > possibility to omit a parameter, which results in an return code of
    > > S_FALSE.
    > > The declaration of the interface would look something like this:
    > >
    > > [pointer_default(unique), ...]
    > > interface IFoo : IUnknown
    > > {
    > > HRESULT GetData( [out]DWORD* pdwSize, [out, size_is( ,*pdwSize)]BYTE**
    > > ppBuffer );
    > > };
    > >
    > > Now, on a usual call like:
    > >
    > > DWORD dwSize;
    > > BYTE* pData;
    > > GetData( &dwSize, &pData );
    > >
    > > everything will be alright.
    > > But what is the behavior, if I call like this:
    > >
    > > BYTE* pData;
    > > GetData( NULL, &pData );
    > >
    > > Even if GetData returns immediately after a paremeter check (allocates no
    > > memory for ppBuffer), COM would try to dereference pdwSize (i.e.
    > > *pdwSize),
    > > which would result in an error.
    > > Am I right, or is COM checking the pointer (pdwSize) first if it is zero
    > > of
    > > not and in case it is zero assumes the dereferenced pointer (*pdwSize) is
    > > zero too?
    > >
    > > In case COM returns an error, is it one which can be handled or is COM
    > > terminating the application?
    > > Of course this is only a point when using a proxy.
    > >
    > > Can anybody help me? Thanks in advance.
    > >
    > > Laurents C. R. Meyer
    >
    >
    >


  • Next message: Laurents C. R. Meyer: "Re: CoInitialize fails with E_ACCESSDENIED after upgrade to XP SP2"

    Relevant Pages

    • Re: Behavior of out parameters and dependencies
      ... ,*pdwSize)]BYTE** ppBuffer); ... > Let's say there is Some Interface called IFoo. ... it is allocated by GetData using CoTaskMemAlloc. ... > interface IFoo: IUnknown ...
      (microsoft.public.win32.programmer.ole)
    • Re: Multiple bounds in a generic declaration
      ... How can I declare this ArrayList? ... both the interface and the listener are existing classes I cannot ... Many of the prebaked existing subclasses of the FormWidget implement ... public class A extends FormWidget implements Listener; ...
      (comp.lang.java.help)
    • Re: Multiple bounds in a generic declaration
      ... Both Foo is an abstract class and Bar is in this case a listener ... How can I declare this ArrayList? ... both the interface and the listener are existing classes I cannot ... Many of the prebaked existing subclasses of the FormWidget implement ...
      (comp.lang.java.help)
    • JDK implementation of inner classes doesnt match Java Language Specification
      ... According to the Java Language Specification 3.0: "A nested class is ... Inner classes may not declare static members, ... interface D //Interface ...
      (comp.lang.java.programmer)
    • Marshal Structure containing arrays to function in DLL
      ... Declare Function nifGetInterfaceList Lib "nifbstd" (ByVal session As Long, ... ByRef info As NifInterfaceInfo) As Long ... Private Sub OpenSess() ... ' Pass the max interface number to function "nifGetInterfaceList" ...
      (microsoft.public.dotnet.languages.vb)