To answer my own question, here's the modified and working code for the archives:

      public override System.Runtime.Remoting.Messaging.IMessage Invoke( 
System.Runtime.Remoting.Messaging.IMessage message )
      {
         System.Runtime.Remoting.Messaging.IMethodCallMessage methodMessage = 
            (System.Runtime.Remoting.Messaging.IMethodCallMessage) message;

         System.Reflection.MethodBase method = methodMessage.MethodBase;

         object returnValue = null;

         object [] tempArgs = methodMessage.Args;

         System.Reflection.ParameterModifier pm =
            new System.Reflection.ParameterModifier( tempArgs.Length );

         IDictionary d = methodMessage.Properties;
         IDictionaryEnumerator e = (IDictionaryEnumerator) d.GetEnumerator();

         while (e.MoveNext())
         {
            Object key = e.Key;
            String keyName = key.ToString();
            Object value = e.Value;

            if ((keyName == "__MethodSignature") && (null != value))
            {
               Type[] args = (Type[])value;

               for(int i = 0; i < args.Length; i++)
               {
                  if(args[i].IsByRef)
                  {
                     pm[i] = true;
                  }
                  else
                  {
                     pm[i] = false;
                  }
               }
               break;
            }
         }
         System.Reflection.ParameterModifier[] pms =
            new System.Reflection.ParameterModifier[ 1 ] { pm };

         // Handle IInterposed methods/properties here.  Right now, there is
         // only one property, so don't do any extensive checking to determine
         // the method being invoked.
         if ( method.DeclaringType == typeof( IInterposed ) )
         {
            returnValue = m_target;
         }
         else
         {
            Type type = m_target.GetType();
            returnValue = type.InvokeMember( method.Name,
                  System.Reflection.BindingFlags.InvokeMethod, null, m_target,
                  tempArgs, pms, null, null );
         }

         System.Runtime.Remoting.Messaging.ReturnMessage returnMessage = 
            new System.Runtime.Remoting.Messaging.ReturnMessage( returnValue, 
                     tempArgs, tempArgs.Length, methodMessage.LogicalCallContext, 
methodMessage );

         return returnMessage;
      }

-- 
- Petter Nilsen, [EMAIL PROTECTED]
Technical Manager, Internet Development, Visma Software ASA


-----Original Message-----
From: Petter Nilsen 
Sent: Thursday, September 26, 2002 10:38 PM
To: [EMAIL PROTECTED]
Subject: Re: [ADVANCED-DOTNET] Interposer class and problems


> Of course, this by itself is not going to work as I've listed it.  You must
> analyze the method being called in terms its parameters.  Each parameter
> will need a corresponding ParameterModifier set properly based on whether
> the parameter is an in-, out-, or ref-type.  You can then make the call (via
> InvokeMember) and copy the modified parameters back into the original
> message...

I did try that one a couple of days ago, but what I didn't do back then was to make a 
copy of the methodMessage.Args array. I did a combination of these two factors now and 
it worked!  

> BTW, I recall an old thread in the DOTNET archives where Adam Nathan talks
> about VT_VARIANT | VT_BYREF not being supported.  I say this because of the
> following function (that was sent to me out-of-band):

> HRESULT bcRACIsEnabled([out] VARIANT *pvtAuthenticationKey, [out]INT*
> piIsEnabled);

> You may find yourself having trouble with this one...

That one actually worked too, so VT_VARIANT | VT_BYREF does work with on [out] 
parameters.

This has been an interesting problem and hopefully I have a solution now that will 
work with all the methods in our legacy COM objects. Thanks a lot for your help!   
Would be useful to update your Interposer class for COM with this code, and post it 
back to gotdotnet.com?

- Petter

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to