Gplus RSS
Home 杂谈 [开源] SoraRTTIReflection 组件
formats

[开源] SoraRTTIReflection 组件

Published on 2011年07月02日 星期六, by darkfall in 杂谈.

Hoshizora核心组件之一

实现了基于C++的RTTI Reflection(反射)

反射能让你在运行时获取类的信息, 例如有哪些变量, 有哪些函数, 类的名字是什么

或者可以通过类名在运行时动态构造类的新实例, 通过函数名和实例在运行时调用类的任意函数等

很多语言已经有Reflection(反射)机制, 比如Java和C#, 但是C++没有

组建在编写过程中参考了Konstatin的cppreflection库, 很多基础来自于他.

PixelLight核心的RTTI Base也给了我一些启发, 那个实现很赞

要使用RTTI Reflection, 你必须手动在编译时给类加上一些描述信息, 例如

class Foo {
public:
	Foo():i(1), j(22) {
		fp = new float(10.f);
	}
	Foo(int _i, int _j): i(_i), j(_j) { fp = new float(10.f); }
	Foo(int _i): i(_i), j(10) { fp = new float(10.f); }

	void foo() { std::cout<<"Hello World!"<<std::endl; }
	virtual int bar(int i) { return i; }
	float* getfp() { return fp; }
	int geti() const { return i; }

	DESCRIBE_CLASS(Foo, (RTTI_DESCRIBED_FIELD(i, int, sora::RTTI_FLAG_PRIVATE),
						 RTTI_FIELD(j, int, sora::RTTI_FLAG_PRIVATE),
						 RTTI_DESCRIBED_PTR(fp, float*, sora::RTTI_FLAG_PRIVATE)),

						(RTTI_METHOD(foo, sora::RTTI_FLAG_PUBLIC),
						 RTTI_METHOD(bar, sora::RTTI_FLAG_PUBLIC | sora::RTTI_FLAG_VIRTUAL),
						 RTTI_METHOD(geti, sora::RTTI_FLAG_PUBLIC),
						 RTTI_METHOD(getfp, 0)),

						RTTI_NO_BASE_CLASS,

						(RTTI_DEFAULT_CONSTRUCTOR(),
						 RTTI_CONSTRUCTOR_1(int),
						 RTTI_CONSTRUCTOR_2(int, int)));

	DESCRIBE_FIELD(i, int);
	DESCRIBE_FIELD(fp, float*);

private:
	int i;
	int j;
	float* fp;
};

注: DESCRIBED_FILED表示可以在运行时set和get的成员变量

然后在全局注册这个到RTTI Class Manager

REGISTRE_CLASS(Foo, 0, 0);

main.cpp里面是使用的例子, 文档暂时没有, 虽说在Sora核心文档内已经写了一部分但不完善, 所以暂时不公开

SoraRTTIReflection at Github

https://github.com/darkfall/SoraRTTIReflection

References:

CppReflection by Konstantin Knizhnil

http://www.garret.ru/cppreflection/docs/reflect.html

PixelLight Core Base

http://www.pixellight.org/site/

3 Responses

  1. 小鱼

    DESCRIBE_CLASS(Foo, (RTTI_DESCRIBED_FIELD(i, int, sora::RTTI_FLAG_PRIVATE), RTTI_FIELD(j, int, sora::RTTI_FLAG_PRIVATE), RTTI_DESCRIBED_PTR(fp, float*, sora::RTTI_FLAG_PRIVATE)), (RTTI_METHOD(foo, sora::RTTI_FLAG_PUBLIC), RTTI_METHOD(bar, sora::RTTI_FLAG_PUBLIC | sora::RTTI_FLAG_VIRTUAL), RTTI_METHOD(geti, sora::RTTI_FLAG_PUBLIC), RTTI_METHOD(getfp, 0)), RTTI_NO_BASE_CLASS, (RTTI_DEFAULT_CONSTRUCTOR(), RTTI_CONSTRUCTOR_1(int), RTTI_CONSTRUCTOR_2(int, int)));

    类似上面的内容,可以采用类似QT的moc技术在编译之前自动生成额外文件来创建反射信息,定义需要反射的类时,只需要对类标识一个可以被识别的标识就好了。
    如此,就不需要对同样的内容进行2次编写,也避免了因为手误带来的隐患。

    [回复]

    darkfall 回复:

    嗯. 之前写的这东西问题还是挺多的
    反射代码自动生成可以写个程序来分析pdb(windows + vs)
    或者用clang之类的前端直接分析代码…
    不过总觉得还是好麻烦=- =

    [回复]

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

欢迎来到GameMaster
-- Studio GameMaster
初音