⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reflect.html

📁 java 反射机制详解示例,实现类属性及方法修改
💻 HTML
📖 第 1 页 / 共 2 页
字号:
        RTTI_FLD_INSTANCE  = 0x0001, 
        RTTI_FLD_STATIC    = 0x0002, 
        RTTI_FLD_CONST     = 0x0004, 
        RTTI_FLD_PUBLIC    = 0x0010, 
        RTTI_FLD_PROTECTED = 0x0020, 
        RTTI_FLD_PRIVATE   = 0x0040, 
        RTTI_FLD_VIRTUAL   = 0x0100, // used for virtual base classes
        RTTI_FLD_VOLATILE  = 0x0200, 
        RTTI_FLD_TRANSIENT = 0x0400
    };
</PRE>

So that is all with describing class field.  Now lets see how methods can be described:

<PRE>
class B : public A { 
    int x;
  public:
    virtual void foo(); 
    char* echo(char* p); 

    RTTI_DESCRIBE_CLASS(B, (RTTI_BASE_CLASS(A, RTTI_FLD_PUBLIC), 
                            RTTI_FIELD(x)),
			   (RTTI_PROC(foo, RTTI_FLD_PUBLIC|RTTI_MTH_VIRTUAL), 
			    RTTI_FUNC(echo, RTTI_FLD_PUBLIC)));
};
	  

RTTI_REGISTER_CLASS(B, 0);
</PRE>

Here class <code>B</code> is declared, which is derived from class A and has methods
<code>foo</code> and <code>echo</code>. As you can see base classes are described within list of 
fields. And array of field descriptors returned by <code>RTTIClassDescriptor::getFields</code> method
also returns field descriptors for base classes (them has <code>RTTIDerivedType</code> type with
tag <code>RTTI_DERIVED</code>). It was done to simplify iteration through the object fields.
Usually, to store/retrieve values of all object fields, recursive method is implemented
which iterate through all fields in the class and is recursively invoked for each compound field.
There is no difference for such method between inherited in included components. 
If base classes are not included in list of fields, then such method has to implement additional loop
through all base classes. And in our case everything can be done within one loop.<P>

When you are describing class with methods, you should use <code>RTTI_DESCRIBE_CLASS</code>
macro instead of  <code>RTTI_DESCRIBE_STRUCT</code>. In this macro you should specify
name of the class, list of the field descriptors and list of method descriptors. 
For describing method two macros are used: <code>RTTI_PROC</code> - for describing void methods 
and <code>RTTI_FUNC</code> for method returning some value.

<H2><A NAME = "limitations">Limitations</A></H2>

In both models of using reflection (explicitly described by programmer and 
extracted from debugging information) there are some limitations.  Below we enumerate them
grouping in three part - common for proposed reflection API and specific for each approach.

<H3>Common limitation</H3>
<UL>
<LI>It is possible to create instance of the object only using default constructor.
<LI>API doesn't support enums, unions and bit fields.
<LI>API provides type only information only about classes and structures used in the application - 
no information about global or static functions and variables is available. 
</UL>

<H3>Limitation of extracting information from descriptors written by programmer</H3>
<UL>
<LI>Only restricted set of field types  is supported (scalars, classes, structures, 
array and pointers of those types, pointer to pointers to those types).
<LI>Methods can not have more than 5 parameters
<LI>It is not possible to describe static methods and fields. 
<LI>Each class should have public default constructor or have no constructors  
at all.
</UL>

<H3>Limitations of extracting types from debug information</H3>
<UL>
<LI>This approach works only under Unix and most probably only with GCC 
(because format of mangling symbols is specific to each compiler)
<LI>It is possible to invoke method only at platforms where parameters are passed through the 
stack (for example Intel). Unfortunately there is no portable way of invoking 
arbitrary method in C++.
<LI>There is no way to distinguish classes defined in application from system classes
which are also extracted from debug information.
<LI>Virtual methods can be invoked only statically (i.e. if you have class <code>A</code> with 
virtual method <code>foo</code> and class <code>B</code> derived from class <code>A</code> which 
overrides <code>foo</code> method, get descriptor of <code>A</code>, find method <code>foo</code> 
in it and invoke this method, then <code>A::foo</code> will be called)
<LI>No field qualifiers (such as <code>const, volatile,...</code>) are currently extracted.
</UL>

<H2><A NAME = "Usage">Usage</A></H2>

To build the package under Window with Microsoft Visual C++, just execute <code>nmake.exe</code>.
It will build <code>reflect.lib</code> library and <code>testrtti.exe</code> example.
To be able to use RTTI in you application, you need to include <code>reflect.h</code>
and <code>typedecl.h</code> header files. Then add type descriptors using macros defined
in <code>typedecl.h</code> header file and decide how you will determine type of the object.
There are several ways of determining object type:<P>

<OL>
<LI>Create base class with virtual method <code>char* getType</code> and derive all classes
for which you want to get runtime type information from this class.
<LI>Use templates to parameterize object type. If you have template parameter <code>T</code>, 
then <code>T::RTTIDesciptor</code> is descriptor of this class.
<LI>Use C++ RTTI mechanism. Once again you need to have some common base class with virtual function.
But it is not necessary to redefine this function in all classes. Instead of it you can 
use RTTI typeof operator to get runtime type of the object, using pointer to this object.
</OL><P>

If you know name of the class, you can locate it in repository using 
<code>RTTIRepository::findClass</code> method. You also can request and iterate
through complete list of application classes (see <code>testrtti.cpp</code> example).<P>
Having class descriptor, it is possible to find field or method with specified name or iterate 
through all components.<P>

At Unix with GCC and GNU make package can be build with <code>make -f makefile.gcc</code>
command. It builds <code>libreflect.a</code> library and <code>testrtti</code> example.
To be able to use debugging information you should change directory to <code>./bfd</code> and do
<code>make</code> here. As a result library <code>libbfdreflect.a</code> and code>testrtti</code> 
example will be build. To extract type descriptors from the image with debugging information
you need both of these libraries (<code>libreflect.a</code> and <code>libbfdreflect.a</code>)
and should use class <code>RTTIBfdRepository</code> instead of <code>RTTIRepository</code>.
The method <code>RTTIBfdRepository::load(char const* filePath)</code> loads debug
information from specified file. Certainly it will be able to it only if image was compiled with 
enabled debug information (<code>-g</code> option for GCC).<P>

<H2><A NAME = "distribution">Distribution terms</A></H2>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the <A HREF="#Software">Software</A>), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:<P>

<A NAME="Software">
<B>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</B>
</A><P>

I will provide e-mail support and help you with development of
CppReflection package.<P>
<HR>
<P ALIGN="CENTER"><A HREF="http://www.garret.ru/~knizhnik">
<B>Look for new version at my homepage</B></A><B> | </B>
<A HREF="mailto:knizhnik@garret.ru">
<B>E-Mail me about bugs and problems</B></A></P>
</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -