[fpc-devel] .NET Reflection vs RTTI

Thorsten Engler thorsten.engler at gmx.net
Tue Nov 20 11:42:54 CET 2007


> I used RTTI to avoid defining an additional constant array of 
> strings to have a unit output debug information for 
> enumerated types. Otherwise I never did see any use of this.
> 
> Could you give a real world  example ?

Do you want a real world example for what better RTTI in general is useful?
Or custom attributes specifically?

For just one of many examples for attributes, just have a look here:

http://msdn2.microsoft.com/en-us/library/Aa480190.aspx

You don't need to read all of it, just search for "[" and have a look at the
code snippets.

Yes, sure there are other ways how you could possibly provide that
information. But custom attributes provide a simple and generic mechanism to
associate runtime dicoverable information with specific types/members of
type. 

As for better runtime information in general, one example of what I've done
myself in Delphi using Interface RTTI (which as I mentioned in another post
is unfortunately rather limited) is something like this:

    function CreateInvokeWrapper(const aInterface   : InxInterface;
                                 const aInterceptor : InxInvokeInterceptor;
                                   out aWrappedIntf : InxInterface)
                                                    : HRESULT;

  InxInvokeInterceptor = interface(InxInterface)
    ['{7DC415F5-B252-457E-A57C-393CD326275C}']

    function InterceptInvoke(aMethod    : PnxIntfMethEntry;
                             aParams    : PnxPointerArray;
                       const aCallFrame : InxCallFrame)
                                        : HRESULT;
  end;

  InxCallFrame = interface(InxInterface)
    ['{6DABF6D0-4419-4074-9CF4-75145AC8A34B}']

    function CopyFrom(aParams : PnxPointerArray)
                              : HRESULT;

    function MakeCall: HRESULT;
  end;

You call CreateInvokeWrapper, passing in an existing interface and a
reference to an interceptor class you implement and get back a new
interface. You can call QueryInterface on that new interface as required to
get other interfaces implemented by the class of the interface you
originally passed in. Any call on a method of any of these wrapped
interfaces ends up in a call to InterceptInvoke where you aMethod gives you
exact information which interface, which method, how many params, param and
result types... aParams then gives you access to the params and result which
allows you to inspect and/or change them. If you want to forward the call
(with possibly changed parameter values) to the inner interface you can call
aCallFrame.MakeCall (but you don't have to) and can then inspect and/or
change the params (might be var and out params among them) and result before
returning. 

Naturally, if I can do that I can also do the 2 half (proxy/stub) in
isolation on different machines which I'm using to implement a remoting
framework: http://nexusdbng.blogspot.com/2007/09/remoting-introduction.html

Cheers,
Thorsten









More information about the fpc-devel mailing list