<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yoichi Kawasaki&#039;s Web &#187; rtti</title>
	<atom:link href="http://yk55.com/blog/tags/rtti/feed/" rel="self" type="application/rss+xml" />
	<link>http://yk55.com/blog</link>
	<description>my publicly accessible private memorandums</description>
	<lastBuildDate>Mon, 14 May 2012 01:31:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	<!-- google_ad_section_end --><!-- google_ad_section_start(weight=ignore) -->	<item>
		<title>C++ :: typeidとdemangleで実行時クラス名取得</title>
		<link>http://yk55.com/blog/2010/01/20/get_cpp_classname_by_typeid_and_demangle/</link>
		<comments>http://yk55.com/blog/2010/01/20/get_cpp_classname_by_typeid_and_demangle/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 20:27:20 +0000</pubDate>
		<dc:creator>yoichi</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cplusplus]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[rtti]]></category>

		<guid isPermaLink="false">http://yk55.com/blog/?p=59</guid>
		<description><![CDATA[Javaでは普通に行われている実行時の型情報取得（ Object.getClass(), Class.getName()とかinstanceOfとかね ）ですが、CではできないのだからどうせC++でもできないのだろうなと思っていたら予想に反しRunＴime Type Identification (RTTI)という実行時の型情報取得機能がばっちり用意されてました。 確かにdynamic_castができているわけだし、まあそういうことだよねと納得。 ということでC++で実行時クラス名の取得を試みました。 実行時型情報取得はtypeid演算子を使います。typeid演算子はtype_info型クラスの参照を返し、そのtype_infoのメンバname()より型情報の文字列が取得できます。 それでは次のコードで型情報を取得してみます。 #include &#60;iostream&#62; #include &#60;typeinfo&#62; using std::cout; using std::endl; using std::type_info; class Parent&#123; public: &#160; virtual void x&#40;&#41;&#123;&#125; &#125;; class Child : public Parent &#123;&#125;; main&#40;&#41;&#123; &#160; &#160; Parent* p; &#160; &#160; p = new Parent&#40;&#41;; &#160; &#160; const type_info &#38; id_p = typeid&#40;*p&#41;; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Javaでは普通に行われている実行時の型情報取得（ Object.getClass(), Class.getName()とかinstanceOfとかね ）ですが、CではできないのだからどうせC++でもできないのだろうなと思っていたら予想に反し<a href="http://en.wikipedia.org/wiki/Run-time_type_information">RunＴime Type Identification (RTTI)</a>という実行時の型情報取得機能がばっちり用意されてました。 確かにdynamic_castができているわけだし、まあそういうことだよねと納得。 ということでC++で実行時クラス名の取得を試みました。</p>
<p>実行時型情報取得は<a href="http://en.wikipedia.org/wiki/Typeid">typeid</a>演算子を使います。typeid演算子は<a href="http://www.cplusplus.com/reference/std/typeinfo/type_info/">type_info</a>型クラスの参照を返し、そのtype_infoのメンバname()より型情報の文字列が取得できます。 それでは次のコードで型情報を取得してみます。</p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#include &lt;iostream&gt;</span><br />
<span style="color: #339900;">#include &lt;typeinfo&gt;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #007788;">type_info</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #0000ff;">class</span> Parent<span style="color: #008000;">&#123;</span><br />
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span><br />
&nbsp; <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> x<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">class</span> Child <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Parent <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<br />
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; Parent<span style="color: #000040;">*</span> p<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Parent<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">const</span> type_info <span style="color: #000040;">&amp;</span> id_p <span style="color: #000080;">=</span> <span style="color: #0000ff;">typeid</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> id_p.<span style="color: #007788;">name</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Child<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">const</span> type_info <span style="color: #000040;">&amp;</span> id_c <span style="color: #000080;">=</span> <span style="color: #0000ff;">typeid</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> id_c.<span style="color: #007788;">name</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>これをコンパイル(gcc 4.3.2)後に実行した結果は次のとおり。</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">6Parent<br />
5Child</div></div>
<p>ParentクラスとChildクラスそれぞれの結果は確かにそれっぽいものが得られましたがなぜかクラス名の前に文字数がくっついてます。 どうしたもんだと思ってググってみるとまさに<a href="http://ml.tietew.jp/cppll/cppll/thread_articles/8646">ピンポイントなMLでの議論</a>を発見。 クラスの前の数字がゴミに見えて気づかなかったのですがこれは<a href="http://en.wikipedia.org/wiki/Name_mangling">マングリング</a>された文字列でした。 というわけで問題はデマングリングで解決します。上記MLではその法についても紹介されていたのでそれを参考にデマングリングを試みます。</p>
<p>デマングリングにはcxxabi.hに定義されている__cxa_demangle()関数を使用します。まずはヘッダを覗いてみます。</p>
<p><u>__cxa_demangle() @ /usr/include/c++/4.1.3/cxxabi.h</u></p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#ifdef __cplusplus</span><br />
<span style="color: #0000ff;">namespace</span> __cxxabiv1<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">extern</span> <span style="color: #FF0000;">&quot;C&quot;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
<span style="color: #339900;">#endif</span><br />
...略...<br />
&nbsp; <span style="color: #666666;">// Demangling routines.</span><br />
&nbsp; <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><br />
&nbsp; __cxa_demangle<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> __mangled_name, <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> __output_buffer,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">size_t</span><span style="color: #000040;">*</span> __length, <span style="color: #0000ff;">int</span><span style="color: #000040;">*</span> __status<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #339900;">#ifdef __cplusplus</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span> <span style="color: #666666;">// namespace __cxxabiv1</span><br />
<span style="color: #339900;">#endif</span><br />
...略...<br />
<span style="color: #666666;">// User programs should use the alias `abi'.</span><br />
<span style="color: #0000ff;">namespace</span> abi <span style="color: #000080;">=</span> __cxxabiv1<span style="color: #008080;">;</span></div></div>
<p>次にこの__cxa_demangle()を使って先のマングルされた文字列をデマングルしてみます。</p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339900;">#include &lt;iostream&gt;</span><br />
<span style="color: #339900;">#include &lt;typeinfo&gt;</span><br />
<span style="color: #339900;">#include &lt;cxxabi.h&gt;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #007788;">type_info</span><span style="color: #008080;">;</span><br />
<br />
<span style="color: #0000ff;">class</span> Parent<span style="color: #008000;">&#123;</span><br />
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span><br />
&nbsp; <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> x<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span> &nbsp;<span style="color: #666666;">// 1. 仮想メソッド宣言</span><br />
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<span style="color: #0000ff;">class</span> Child <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Parent <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span><br />
<br />
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; Parent<span style="color: #000040;">*</span> p<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">int</span> status<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Parent<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">const</span> type_info <span style="color: #000040;">&amp;</span> id_p <span style="color: #000080;">=</span> <span style="color: #0000ff;">typeid</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> abi<span style="color: #008080;">::</span>__cxa_demangle<span style="color: #008000;">&#40;</span>id_p.<span style="color: #007788;">name</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">0</span>, <span style="color: #000040;">&amp;</span>status<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Child<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">const</span> type_info <span style="color: #000040;">&amp;</span> id_c <span style="color: #000080;">=</span> <span style="color: #0000ff;">typeid</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> abi<span style="color: #008080;">::</span>__cxa_demangle<span style="color: #008000;">&#40;</span>id_c.<span style="color: #007788;">name</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">0</span>, <span style="color: #000040;">&amp;</span>status<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>デマングル版コードをコンパイル(gcc 4.3.2)後に実行してみると無事クラス名が出力。 ということで見事実行時クラス名の取得に成功しました。</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Parent<br />
Child</div></div>
<p>おわり</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http://yk55.com/blog/2010/01/20/get_cpp_classname_by_typeid_and_demangle/&amp;layout=button_count&amp;show_faces=1&amp;width=450&amp;action=like&amp;colorscheme=light&amp;font=arial" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:25px"></iframe>]]></content:encoded>
			<wfw:commentRss>http://yk55.com/blog/2010/01/20/get_cpp_classname_by_typeid_and_demangle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	<!-- google_ad_section_end --></channel>
</rss>

