Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3270992
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T18:41:18+00:00 2026-05-17T18:41:18+00:00

I’m working up a system where I plan on using RealProxy objects to enable

  • 0

I’m working up a system where I plan on using RealProxy objects to enable intercepting method calls against a set of objects, handling the call, and then returning appropriate results.

This works just find for simple return types like strings or ints, but I can’t seem to return objects from the RealProxy.Invoke method.

Everything works. I get no errors, but the returned value is always NOTHING, instead of an object.

I’ve worked up the smallest sample code I could, and have included it below.

Essentially, just call RPtest and single step through.
The code creates a simple object, RPTestA, with a string field and an object valued field
It then retrieves the string
Dim x = c.Name
Which works fine
and then attempts to retrieve the object

Dim r = c.SubObj

Which always returns nothing.

However, in the FieldGetter routine, this code:

'---- the field is an OBJECT type field  
Dim mc = New MethodCallMessageWrapper(Msg)  

'---- create the object  
Dim o = Activator.CreateInstance(t)  
'---- and construct the return message with that object  
Dim r = New ReturnMessage(o, mc.Args, mc.Args.Length, mc.LogicalCallContext, mc)  
Return r  

appears to work just fine, setting the ReturnValue field of the ReturnMessage to the object that was created by the Activator.CreateInstance(t) call just above.

I suspect it’s a serialization thing of some sort, but I’m at a loss.

You should be able to run this code straight away, but just pasting it into a new VB.net project.

'----------------------------------------------------------------------------
Imports System.Security.Permissions
Imports System.Diagnostics
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.Serialization
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Activation
Imports System.Runtime.Remoting.Messaging
Imports System.Runtime.Remoting.Proxies


Public Module RPTest
    Public Sub RPTest()
        '---- create a new object that is automatically proxied
        '     See the RPProxyAttribute for details
        Dim c = New RPTestA

        Dim x = c.Name
        'x is returned as a string value just fine
        Dim r = c.SubObj
        '********* PROBLEM IS HERE, r ends up nothing
    End Sub
End Module


'ROOT test object
Public Class RPTestA
    Inherits RPBase

    Public Name As String = "Test Name"
    Public SubObj As RPTestB

End Class


'SUB OBJECT which should be returned as a field value from the root object above
Public Class RPTestB
    Inherits RPBase

    Public SubProperty As String = "SubObj Test Property"
End Class


''' <summary>
''' Base proxyable object class
''' </summary>
''' <remarks></remarks>
<RPProxy()> _
Public MustInherit Class RPBase
    Inherits ContextBoundObject

End Class


<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
Public Class RPProxy
    Inherits RealProxy

    Private m_target As MarshalByRefObject


    Public Sub New()
        m_target = DirectCast(Activator.CreateInstance(GetType(ConfigRP)), MarshalByRefObject)
        Dim myObjRef = RemotingServices.Marshal(m_target)
    End Sub

    Public Sub New(ByVal classToProxy As Type)
        MyBase.New(classToProxy)
    End Sub


    Public Sub New(ByVal ClassToProxy As Type, ByVal targetObject As MarshalByRefObject)
        m_target = targetObject
        Dim myObjRef = RemotingServices.Marshal(m_target)
    End Sub


    Public Overrides Function Invoke(ByVal msg As IMessage) As IMessage
        Dim returnMsg As IMethodReturnMessage = Nothing

        If TypeOf msg Is IConstructionCallMessage Then
            '---- handle constructor calls
            Dim ConstructionCallMessage = DirectCast(msg, IConstructionCallMessage)
            returnMsg = InitializeServerObject(ConstructionCallMessage)
            Me.m_target = Me.GetUnwrappedServer()
            SetStubData(Me, Me.m_target)
            Return returnMsg

        ElseIf TypeOf msg Is IMethodCallMessage Then
            '---- handle all other method calls
            Dim methodCallMessage = DirectCast(msg, IMethodCallMessage)

            '---- before message processing
            preprocess(methodCallMessage)

            '---- execute the method call
            Dim rawReturnMessage = RemotingServices.ExecuteMessage(Me.m_target, methodCallMessage)

            '---- and postprocess
            returnMsg = postprocess(methodCallMessage, rawReturnMessage)

        Else
            Throw New NotSupportedException()
        End If

        Return returnMsg
    End Function


    'Called BEFORE the actual method is invoked
    Private Sub PreProcess(ByVal msg As IMessage)
        Console.WriteLine("before method call...")
    End Sub


    'Called AFTER the actual method is invoked
    Private Function PostProcess(ByVal Msg As IMethodCallMessage, ByVal msgReturn As ReturnMessage) As ReturnMessage
        Dim r As ReturnMessage
        If Msg.MethodName = "FieldGetter" Then
            r = FieldGetter(Msg, msgReturn)
        ElseIf Msg.MethodName = "FieldSetter" Then
            'na
            r = msgReturn
        ElseIf Msg.MethodName.StartsWith("get_") Then
            'na
            r = msgReturn
        ElseIf Msg.MethodName.StartsWith("set_") Then
            'na
            r = msgReturn
        Else
            r = msgReturn
        End If
        Return r
    End Function


    Private Function FieldGetter(ByVal Msg As IMethodCallMessage, ByVal msgReturn As IMethodReturnMessage) As IMethodReturnMessage
        Dim t = Me.Target.GetType

        '---- This retrieves the type of the field that the getter should retrieve
        t = t.GetField(Msg.InArgs(1), BindingFlags.Instance Or BindingFlags.Public).FieldType

        If t.Name = "String" Then
            '---- just return what the object returned as a result of ExecuteMessage
            Return msgReturn

        ElseIf t.BaseType.Equals(GetType(RPBase)) Then
            '---- the field is an OBJECT type field
            Dim mc = New MethodCallMessageWrapper(Msg)
            '---- create the object
            Dim o = Activator.CreateInstance(t)
            '---- and construct the return message with that object
            Dim r = New ReturnMessage(o, mc.Args, mc.Args.Length, mc.LogicalCallContext, mc)
            Return r

        Else
            Return msgReturn
        End If
    End Function


    Public Property Target() As Object
        Get
            Return Me.m_target
        End Get
        Set(ByVal value As Object)
            Me.m_target = value
        End Set
    End Property
End Class


<AttributeUsage(AttributeTargets.Class)> _
<SecurityPermissionAttribute(SecurityAction.Demand, Flags:=SecurityPermissionFlag.Infrastructure)> _
Public Class RPProxyAttribute
    Inherits ProxyAttribute


    Public Overrides Function CreateInstance(ByVal Type As Type) As MarshalByRefObject
        Dim proxy = New RPProxy(Type)
        Dim transparentProxy = DirectCast(proxy.GetTransparentProxy(), MarshalByRefObject)
        Return transparentProxy
    End Function
End Class
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T18:41:18+00:00Added an answer on May 17, 2026 at 6:41 pm

    Well, it turns out to be a pretty simple fix, once you work past the god awful ReturnMessage constructor that’s quite misleading!

    Many thanks to an old colleague of mine, Rich Quackenbush, for taking a few minutes and checking this out. Sometimes, you can’t see the forest for the trees!

    Anyway, in FieldGetter, I was doing this

    ElseIf t.BaseType.Equals(GetType(RPBase)) Then
            '---- the field is an OBJECT type field
            Dim mc = New MethodCallMessageWrapper(Msg)
            '---- create the object
            Dim o = Activator.CreateInstance(t)
            '---- and construct the return message with that object
            Dim r = New ReturnMessage(o, mc.Args, mc.Args.Length, mc.LogicalCallContext, mc)
            Return r
    

    Seems completely reasonable, that newly created object being passed into the ReturnMessage constructor argument called ReturnValue.

    But no. You actually have to create an object array and pass it is as the 3 element in that array, like this:

    ElseIf t.BaseType.Equals(GetType(RPBase)) Then
            '---- the field is an OBJECT type field
            Dim mc = New MethodCallMessageWrapper(Msg)            '---- create the object
            Dim o = Activator.CreateInstance(t)
            '---- and construct the return message with that object
            Dim r = New ReturnMessage(Nothing, New Object() {Nothing, Nothing, o}, 3, mc.LogicalCallContext, mc)
            Return r
    

    It turns out, this is because the FieldGetter function is what in being “called” and intercepted by the proxy, and it’s signature is

    FieldGetter(StringtypeName,StringfieldName,Object&val)
    

    Which, for purposes of constructing a ReturnMessage for that call means that it doesn’t have a Returnvalue at all, but rather that the return value is returned as the 3’rd argument in that list.

    Since I’m not actually calling the real FieldGetter function, the first two argument (the typename and fieldname) are immaterial, but that 3’rd argument is the proper place to put the return value.

    It’s always obvious in hindsight!

    Many thanks to Rich.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.