Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace System.Runtime.Remoting.Proxies
{
//透明代理类
internal sealed class __TransparentProxy
{
// Fields
/*
* 接口方法表指针,这是透明代理的一个特殊之处。一个TP实例可以伪装成一个类同时另外实现一个接口
* 也就是说TP实例看起来像是这样的一个对象,这个对象是类型A的实例,但同时又可以动态的实现一个无关接口B
* A obj = new A();
* A insert interface B;
* B i = (B)obj;
*/
private IntPtr _pInterfaceMT;
/*
* 方发表指针,此指针定义了TP实例的表现类型
* 如果要构造TP实例,必须同时拥有此类型和上面接口的元数据
* 非托管代码可以访问实例拥有的所有字段,而不像非托管代码那样只能访问显式声明字段
* 也就是说实例上的所有字段对于非托管代码来说都是一样的
*/
private IntPtr _pMT;
/*
* 每一个TP实例和一个RP实例一一对应
*/
private RealProxy _rp;
/*
* 为了实现消息截获,TP必须知道如何解析堆栈上的数据
* 调用不同方法时堆栈上参数的结构也不同
* 因此需要通过_pInterfaceMT和_pMT所指向的元数据,在运行时动态生成解析函数
* 之所以说是动态生成而不是静态生成,是因为TP在程序集中是不可见的,也就是在IL里根本就没有影(所谓的透明)
* TP由JIT构造完成。JIT在编译涉及到MarshalByRefObject的访问时发出不同的指令
* 对一个对象的访问可以分为两种类型,方法调用和传递引用。传递引用的时候实际上并不是对对象的访问,只是传递引用。
* 如果引用的是TP那么传递的就是TP的引用
* 实际上需要考虑的只是针对对象的方法调用
* 方法调用的本质是将对象引用压入堆栈,并将参数入栈,并在方法返回后清理方法使用的堆栈将返回值放在堆栈上
* 这一过程可以本看作是消息的发送与接收,堆栈是发送消息和接收消息的中介
* 调用者将一个消息放置在堆栈上,过一会又从堆栈上接收被调用函数的返回消息
* JIT首先根据元数据生成类型和接口存根函数,这些函数用于将堆栈上的消息封装到一个MessageData对象中去
* 其次JIT在编译对MBR对象的访问IL指令时,发射这些存根函数
* 对于new操作来说,实际上两个操作,分配空间和调用ctor
* MBR对象有自己的特殊的new实现。所有从MarshalByRefObject派生的对象共享同一个new实现,所有普通对象共享另一个
* MBR对象的new实现实现了构造拦截
*/
private IntPtr _stub;
/*
* 可能是_stub实现上所需要的一些实例数据
*/
private object _stubData;
// Methods
private __TransparentProxy();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace System.Runtime.Remoting.Proxies
{
//透明代理类
internal sealed class __TransparentProxy
{
// Fields
/*
* 接口方法表指针,这是透明代理的一个特殊之处。一个TP实例可以伪装成一个类同时另外实现一个接口
* 也就是说TP实例看起来像是这样的一个对象,这个对象是类型A的实例,但同时又可以动态的实现一个无关接口B
* A obj = new A();
* A insert interface B;
* B i = (B)obj;
*/
private IntPtr _pInterfaceMT;
/*
* 方发表指针,此指针定义了TP实例的表现类型
* 如果要构造TP实例,必须同时拥有此类型和上面接口的元数据
* 非托管代码可以访问实例拥有的所有字段,而不像非托管代码那样只能访问显式声明字段
* 也就是说实例上的所有字段对于非托管代码来说都是一样的
*/
private IntPtr _pMT;
/*
* 每一个TP实例和一个RP实例一一对应
*/
private RealProxy _rp;
/*
* 为了实现消息截获,TP必须知道如何解析堆栈上的数据
* 调用不同方法时堆栈上参数的结构也不同
* 因此需要通过_pInterfaceMT和_pMT所指向的元数据,在运行时动态生成解析函数
* 之所以说是动态生成而不是静态生成,是因为TP在程序集中是不可见的,也就是在IL里根本就没有影(所谓的透明)
* TP由JIT构造完成。JIT在编译涉及到MarshalByRefObject的访问时发出不同的指令
* 对一个对象的访问可以分为两种类型,方法调用和传递引用。传递引用的时候实际上并不是对对象的访问,只是传递引用。
* 如果引用的是TP那么传递的就是TP的引用
* 实际上需要考虑的只是针对对象的方法调用
* 方法调用的本质是将对象引用压入堆栈,并将参数入栈,并在方法返回后清理方法使用的堆栈将返回值放在堆栈上
* 这一过程可以本看作是消息的发送与接收,堆栈是发送消息和接收消息的中介
* 调用者将一个消息放置在堆栈上,过一会又从堆栈上接收被调用函数的返回消息
* JIT首先根据元数据生成类型和接口存根函数,这些函数用于将堆栈上的消息封装到一个MessageData对象中去
* 其次JIT在编译对MBR对象的访问IL指令时,发射这些存根函数
* 对于new操作来说,实际上两个操作,分配空间和调用ctor
* MBR对象有自己的特殊的new实现。所有从MarshalByRefObject派生的对象共享同一个new实现,所有普通对象共享另一个
* MBR对象的new实现实现了构造拦截
*/
private IntPtr _stub;
/*
* 可能是_stub实现上所需要的一些实例数据
*/
private object _stubData;
// Methods
private __TransparentProxy();
}
}