<?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>Music Sets Me Free</title>
	<atom:link href="http://www.bennychen.cn/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.bennychen.cn</link>
	<description>Whatever Keeps Situation Sharp</description>
	<lastBuildDate>Sun, 05 Sep 2010 06:29:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Using Blocked Dropbox under Linux</title>
		<link>http://www.bennychen.cn/?p=1055</link>
		<comments>http://www.bennychen.cn/?p=1055#comments</comments>
		<pubDate>Sun, 05 Sep 2010 04:19:47 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[blocked]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[gstm]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[proxychains]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=1055</guid>
		<description><![CDATA[Recently I&#8217;ve been starting to use Ubuntu. I am just a newbie to Linux, so everything seems hard for me on the first time. No matter how familiar we are with Windows, when transferred to the Linux world, we become a computer idiot again. But everything is also fresh and attractive for me. When I [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been starting to use Ubuntu. I am just a newbie to Linux, so everything seems hard for me on the first time. No matter how familiar we are with Windows, when transferred to the Linux world, we become a computer idiot again. But everything is also fresh and attractive for me. When I get my first Ubuntu 10.04 (the latest version at this time) work on my laptop, I was totally shocked, really bloody cool~ (I learned the word &#8220;bloody&#8221; from a British TV show called IT Crowd, which I am watching recently)</p>
<p>Dropbox is a perfect software to sync your files among different computers and I use it quite often under Windows. And now under Linux, I want it, too. But here in China, Dropbox is violently blocked. So in order to use it, I need to get out of the firewall first.</p>
<p><strong>Get an SSH tunnel</strong><br />
It&#8217;s a common way to use SSH to get over the wall. Getting an SSH tunnel is easy, there are some for free. And you could also buy one for the sake of stability and speed. I bought a Puff (which is a kind of software using SSH) account from China&#8217;s biggest C2C shopping site Taobao.com.</p>
<p><strong>Use gSTM as the SSH tunnel manager under Linux</strong><br />
Get gSTM from here: <a href="http://sourceforge.net/projects/gstm/">http://sourceforge.net/projects/gstm/</a><br />
Configure gSTM:</p>
<ul>
<li>click &#8216;Add&#8217; button to add a tunnel;</li>
<li>input the host and login username of the tunnel you get from the last step;</li>
<li>click &#8216;Add&#8217; button to add a port redirection, set Type=dynamic, Port=7070 (the common SSH port), To host=n/a, To Port=n/a.</li>
</ul>
<p>Start the tunnel you&#8217;ve just added. If you set your browser&#8217;s proxy as SOCK5, 127.0.0.1:7070, you should be able to surf the sites like Facebook and Twitter now. If so, certainly you can log on to www.dropbox.com too!</p>
<p><strong>Download Dropbox for Linux</strong><br />
Go to <a href="https://www.dropbox.com/downloading">https://www.dropbox.com/downloading</a>, and download a Dropbox for linux. I&#8217;m using Ubuntu, so I downloaded the Ubuntu (x86 .deb). Double click the downloaded .deb file, it will start the Ubuntu&#8217;s package installer to install Dropbox.</p>
<p><strong>Download Dropbox daemon</strong><br />
After installation and starting Dropbox, it will prompt you to download the Dropbox daemon, but the proxy we set up before only works for the browser, so I cannot get the downloading work. The problem here is how could I let an arbitrary software to access the Internet with proxy. The solution is to use ProxyChains.</p>
<p><strong>Use ProxyChains</strong><br />
Install ProxyChains: sudo apt-get install ProxyChains<br />
Configuration</p>
<ul>
<li> open configuration file ( /etc/proxychains.conf )</li>
<li> modify the last line from &#8220;socks4 127.0.0.1 9050&#8243; to &#8220;socks5 127.0.0.1 7070&#8243;</li>
</ul>
<p>Now you should be able to use the SSH proxy to download Dropbox daemon.<br />
Open terminal, and enter: proxychains dropbox start -i</p>
<p>This will start Dropbox with the SSH proxy. After the daemon is downloaded and installed, we could enjoy Dropbox again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=1055</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>小心DLL链接静态库时的内存错误</title>
		<link>http://www.bennychen.cn/?p=1028</link>
		<comments>http://www.bennychen.cn/?p=1028#comments</comments>
		<pubDate>Thu, 02 Sep 2010 14:05:58 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Some Experiences]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[_CrtIsValidHeapPointer]]></category>
		<category><![CDATA[静态库]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=1028</guid>
		<description><![CDATA[最近写的模块，在独立的应用程序中测试是没问题的，但把它装配成DLL后，再在另一个应用程序中调用时却出现了内存错误。程序的模块链接关系大概是这样的： module就是我所写的模块，在这里被封装为DLL，因为要使用json相关的功能，该DLL链接了一个静态库 (jsoncpp.lib)。最后在应用程序中导入并使用module.dll，同时因为在应用程序中也需要用到json，所以应用程序也链接了jsoncpp.lib。 以下用一些伪代码来描述这些模块间的调用关系，以具现出这个错误。 jsoncpp.lib为c++提供了功能齐全的json操作，其核心的类是Json::Value。（阅读本篇文章你无需了解太多json） module.dll中导出了一个接口： //ModuleClass.h #include &#34;json/value.h&#34; #if defined MODULE_EXPORTS #define MODULE_EXPORTS __declspec(dllexport) #else #define MODULE_EXPORTS __declspec(dllimport) #endif class ModuleClass { public: MODULE_EXPORTS void AllocSomeMemory( Json::Value &#38;root ) { // 这将申请一些内存，因为会new出一个Json::Value，并append到root上 root.append( &#34;testString&#34; ); } }; 应用程序： #include &#34;json/value.h&#34; #include &#34;ModuleClass.h&#34; int main() { Json::Value root; ModuleClass::AllocSomeMemory( root ); } 在Debug模式下，当main函数执行完毕，对Json::Value root进行析构时，程序便出现了异常。分析下，很显然，调用ModuleClass::MallocMemoryHere时申请的内存，是在module.dll中申请的，而对这些内存的析构则是在应用程序（.exe）中进行的（析构root会同时析构append在root上的所有子Json::Value）。不过，这是异常的真正原因么？ 追踪到异常的出错点：dbgheap.c文件中那句ASSERT语句。 [...]]]></description>
			<content:encoded><![CDATA[<p>最近写的模块，在独立的应用程序中测试是没问题的，但把它装配成DLL后，再在另一个应用程序中调用时却出现了内存错误。程序的模块链接关系大概是这样的：</p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/09/PixiuLog.png" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-full wp-image-1029" title="lib_dll_exe" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/09/PixiuLog.png" alt="" width="249" height="234" /></a></p>
<p>module就是我所写的模块，在这里被封装为DLL，因为要使用json相关的功能，该DLL链接了一个静态库 (jsoncpp.lib)。最后在应用程序中导入并使用module.dll，同时因为在应用程序中也需要用到json，所以应用程序也链接了jsoncpp.lib。</p>
<p>以下用一些伪代码来描述这些模块间的调用关系，以具现出这个错误。</p>
<p>jsoncpp.lib为c++提供了功能齐全的json操作，其核心的类是Json::Value。（阅读本篇文章你无需了解太多json）</p>
<p>module.dll中导出了一个接口：</p>
<pre class="brush: cpp;">
//ModuleClass.h
#include &quot;json/value.h&quot;

#if defined MODULE_EXPORTS
#define MODULE_EXPORTS __declspec(dllexport)
#else
#define MODULE_EXPORTS __declspec(dllimport)
#endif

class ModuleClass
{
public:
	MODULE_EXPORTS void AllocSomeMemory( Json::Value &amp;root )
	{
		// 这将申请一些内存，因为会new出一个Json::Value，并append到root上
		root.append( &quot;testString&quot; );
	}
};
</pre>
<p>应用程序：</p>
<pre class="brush: cpp;">
#include &quot;json/value.h&quot;
#include &quot;ModuleClass.h&quot;
int main()
{
	Json::Value root;
	ModuleClass::AllocSomeMemory( root );
}
</pre>
<p>在Debug模式下，当main函数执行完毕，对Json::Value root进行析构时，程序便出现了异常。分析下，很显然，调用ModuleClass::MallocMemoryHere时申请的内存，是在module.dll中申请的，而对这些内存的析构则是在应用程序（.exe）中进行的（析构root会同时析构append在root上的所有子Json::Value）。不过，这是异常的真正原因么？</p>
<p>追踪到异常的出错点：dbgheap.c文件中那句ASSERT语句。</p>
<pre class="brush: cpp;">
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
</pre>
<p>注释中的最后一句话”The pointer MUST come from the &#8216;local&#8217; heap“引起了我的警惕，难道对于内存的申请和释放不是在同一个heap上，除了‘local&#8217; heap还有一个什么heap么。</p>
<p>去MSDN上搜索了关于_CrtIsValidHeapPointer，似乎找到了答案，以下这段话是MSDN上对于_CrtIsValidHeapPointer的介绍：</p>
<blockquote><p>The _CrtIsValidHeapPointer function is used to ensure that a specific memory address is within the local heap. The local heap refers to the heap created and managed by a particular instance of the C run-time library. <strong>If a dynamic-link library (DLL) contains a static link to the run-time library, it has its own instance of the run-time heap, and therefore its own heap, independent of the application&#8217;s local heap.</strong> When _DEBUG is not defined, calls to _CrtIsValidHeapPointer are removed during preprocessing.</p></blockquote>
<p>注意字体加粗的部分，这不正应对我的情形么？！错误不在于DLL中申请的内存在EXE中释放，而在于如果这个DLL拥有一个静态链接，它就会拥有独立的运行时堆，独立于应用程序的堆。这样对于内存申请和释放并不是在同一个堆上进行的，当然出错了。</p>
<p>解决：虽然MSDN上最后说，如果把项目改成release的，这个ASSERT就将避免，但这是放纵内存泄露，最好的解决办法是将静态链接也改成动态链接，这样就使得DLL能够和应用程序共享同一个堆，错误也得以避免。</p>
<p>于是，我修改了jsoncpp的项目配置，生成jsoncpp的动态链接库，而不是使用静态库，重新导入到module.dll中，错误解决。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=1028</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Static Initialization Order Fiasco</title>
		<link>http://www.bennychen.cn/?p=999</link>
		<comments>http://www.bennychen.cn/?p=999#comments</comments>
		<pubDate>Thu, 19 Aug 2010 04:59:45 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[static initialization order fiasco]]></category>
		<category><![CDATA[初始化]]></category>
		<category><![CDATA[崩溃]]></category>
		<category><![CDATA[静态变量]]></category>
		<category><![CDATA[顺序]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=999</guid>
		<description><![CDATA[Static Initialization Order Fiasco (SIOF)，我也是最近才知道了这个说法，因为在开发程序的时候被它bug了：对于一个static变量，不管它是全局的或者是类的成员变量，访问它的时候不一定总是成功的，甚至会造成程序crash，因为不能保证它在被访问时已经被初始化了（跟初始化的顺序有关，所以称为初始化顺序的Fiasco）。以下将制造一个非常简单的SIOF情形： Whatever.h #include &#60;vector&#62; #include &#60;string&#62; class Whatever { public: Whatever() { cout &#60;&#60; &#34;Construct Whatever&#34; &#60;&#60; endl; Display(); } ~Whatever() { cout &#60;&#60; &#34;Destruct Whatever&#34; &#60;&#60; endl; Display(); } void Display() { cout &#60;&#60; &#34;static int:&#34; &#60;&#60; i &#60;&#60; endl; cout &#60;&#60; &#34;static string:&#34; &#60;&#60; m_str &#60;&#60; endl; cout &#60;&#60; [...]]]></description>
			<content:encoded><![CDATA[<p>Static Initialization Order Fiasco (SIOF)，我也是最近才知道了这个说法，因为在开发程序的时候被它bug了：对于一个static变量，不管它是全局的或者是类的成员变量，访问它的时候不一定总是成功的，甚至会造成程序crash，因为不能保证它在被访问时已经被初始化了（跟初始化的顺序有关，所以称为初始化顺序的Fiasco）。以下将制造一个非常简单的SIOF情形：</p>
<p>Whatever.h</p>
<pre class="brush: cpp;">
#include &lt;vector&gt;
#include &lt;string&gt;
class Whatever
{
public:
	Whatever()
	{
		cout &lt;&lt; &quot;Construct Whatever&quot; &lt;&lt; endl;
		Display();
	}
	~Whatever()
	{
		cout &lt;&lt; &quot;Destruct Whatever&quot; &lt;&lt; endl;
		Display();
	}
	void Display()
	{
		cout &lt;&lt; &quot;static int:&quot; &lt;&lt; i &lt;&lt; endl;
		cout &lt;&lt; &quot;static string:&quot; &lt;&lt; m_str &lt;&lt; endl;
		cout &lt;&lt; &quot;static vector:&quot; &lt;&lt; m_vec.front() &lt;&lt; endl;
	}

private:
	static int i;
	static std::string m_str;
	static std::vector&lt;char&gt; m_vec;
};
</pre>
<p>Whatever.cpp</p>
<pre class="brush: cpp;">
#include &quot;Whatever.h&quot;

int Whatever::i = 500；
string Whatever::m_str = &quot;something&quot;;
vector&lt;char&gt; Whatever::m_vec = vector&lt;char&gt;( 10, 'a' );
</pre>
<p>一个简单的类，Whatever，包含几个static成员变量，然后在构造函数和析构函数中都分别打印这些静态变量的值，乍一看似乎没什么问题，但却有潜在的SIOF的风险。我们容易默认为在调用Whatever的构造函数的时候，Whatever空间中的static的成员变量已经被初始化了，其实不然，现在制造一个SIOF引起crash的情形：</p>
<pre class="brush: cpp;">
#include &quot;Whatever.h&quot;
Whatever g_whatever;
int main()
{
	...
}
</pre>
<p>因为g_whatever是global变量，所以最先被初始化，在调用Whatever的构造函数的时候，Whatever空间的静态成员变量还未被初始化，所以访问这些静态变量肯定出错。在VS的编译器下测试的结果：</p>
<blockquote><p>Construct Whatever<br />
static int:5<br />
static string:<br />
（调用m_vec.front()导致程序crash）</p></blockquote>
</blockquote>
<p>奇怪的是对于int这种built-in的类型却能得到正确的值，不知编译器在背后都做了哪些手脚，猜想可能是在程序编译的时候他们就被值替换了。而string和vector应该都属于自定义类型（初始化需要调用构造函数），未初始化之前访问肯定是错误的，所以打印出的string是个空值，而访问一个空的vector的front元素则直接造成程序crash。</p>
<p>根据初始化和释放的对称关系，所以在析构函数中访问这些静态变量同样也是失败的，因为在析构g_whatever的时候，Whatever空间的静态变量已经被解决掉了。</p>
<p>SIOF是非常难于检测的问题，这个例子是一种最简单的情形，在我的项目中，我并没有定义什么global的成员，但是因为使用了很多前置声明（forward declaration），还有一些Singleton，造成了一个非常隐蔽的SIOF，花了很大的力气才找到，痛苦的过程。</p>
<p>要解决SIOF问题，需要用一个function来包装static变量，即利用函数内static变量的construct-on-first-use特性。</p>
<p>修改后的Whatever.h</p>
<pre class="brush: cpp;">
class Whatever
{
public:
	Whatever()
	{
		cout &lt;&lt; &quot;Construct Whatever&quot; &lt;&lt; endl;
		Display();
	}
	~Whatever()
	{
		cout &lt;&lt; &quot;Destruct Whatever&quot; &lt;&lt; endl;
		Display();
	}
	void Display()
	{
		cout &lt;&lt; &quot;static vector:&quot; &lt;&lt; GetStaticVector().front() &lt;&lt; endl;
	}

private:
	vector&lt;char&gt;&amp; GetStaticVector()
	{
		static vector&lt;char&gt; vec = vector&lt;char&gt;( 10, 'a' );
		return vec;
	}
};
</pre>
<p>用GetStaticVector来包装之前所需要的静态的vector，就能保证在调用的时候，它一定已经被初始化了。再次运行之前的测试程序，OK了。</p>
<p>总之，我们对于static变量的使用要保持一颗警惕的心，如果不确定在使用时它是否已经被初始化，就要使用函数包装static变量来防止Static Initialization Order FIASCO!<br />
Fiasco, what a cool word.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=999</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让管理lua_State的类指针安全</title>
		<link>http://www.bennychen.cn/?p=976</link>
		<comments>http://www.bennychen.cn/?p=976#comments</comments>
		<pubDate>Sun, 15 Aug 2010 08:35:49 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Game Programming]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[copy]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[lua_State]]></category>
		<category><![CDATA[pointer]]></category>
		<category><![CDATA[safe]]></category>
		<category><![CDATA[shared_ptr]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[指针]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=976</guid>
		<description><![CDATA[最近因为在公司的项目中接手了Lua脚本模块的开发，所以研究了很多关于Lua脚本的东西，秉着“多看多想多记”的原则，我时刻敦促自己要及时记录下遇到的一些问题和想法。 在Lua中，几乎所有的东西都是围绕着lua_State转，所以，一般我们都会写一个类来封装管理它，比如： class LuaObject { public: LuaObject() { m_L = luaL_newstate(); luaL_openlibs( m_L ); } ~LuaObject() { if ( m_L ) { lua_close( m_L ); m_L = NULL; } } private: lua_State *m_L; }; 这很好，不过它不是指针安全的。试想，如果一个LuaObject对象被复制，结果将会怎样。 LuaObject luaObject1; LuaObject luaObject2( luaObject1 ); 上面这段代码将会导致运行时crash，因为luaObject1和luaObject事实上指向了同一块lua_State，这样当luaObject1和luaObject2被析构时，lua_State会被两次lua_close，这不crash才怪呢！ 事实是，当一个类包含了一个指针时，我们就需要开始变得格外谨慎，除了在构造函数和析构函数中要处理指针的初始化和清理外，我们还需要考虑深拷贝（deep copy），浅拷贝（shallow copy)）的问题。如果使用编译器默认生成的拷贝构造函数，它只会浅拷贝指针，而指针所指向的内存区域不会被拷贝。就像上面一样，两个LuaObject实则共享了一个lua_State。 那该如何处理让管理LuaObject类的指针安全呢，深拷贝？厄，首先我也没有深究深度拷贝lua_State具体该如何完成，不过我猜想这可是一个复杂而重型的操作，仅仅为了带来指针安全而选择此可不是一个明智的选择。 如果你是开发LuaObject类的程序员，也许你会对使用LuaObject的程序员（或许有时使用者就是你自己）说：“你不要对它进行拷贝操作不就OK了”，但这是一种严重不负责任的行为，因为这种皮球会越踢越远的。比如，程序员A使用了你的LuaObject类，他写了一个包含LuaObject的指针的类，同样A也不考虑拷贝指针安全问题，然后A又将它的类传递给了B，B封装了A的类指针，然后传递给了C，接着如此重复，C再给D，D再给E，最后E在对类进行拷贝操作时，程序crash掉了，因为在某个最底层，他们共享了lua_State。不过因为这时候已经嵌套了这么多层，E程序员或许根本不知道也不关心什么是LuaObject（他只跟D的类打交道）。这时，要想追踪到BUG之源——万恶的不考虑指针安全的LuaObject，已经非常困难了，God bless you all. 事实是，如果你不想让你的类被复制，你就应该明确而显示的禁止它。其实lua_State的这个问题非常类似于Effective C++书中的第14个条款中所提到的问题：在资源管理类中小心copying行为。对于这个问题，书中提供了两种解决方案。第一种就是禁止复制。第二种则是对底层资源的“引用计数法”（reference count）。 第一种禁止复制很简单。（关于Uncopyable） class [...]]]></description>
			<content:encoded><![CDATA[<p>最近因为在公司的项目中接手了Lua脚本模块的开发，所以研究了很多关于Lua脚本的东西，秉着“多看多想多记”的原则，我时刻敦促自己要及时记录下遇到的一些问题和想法。</p>
<p>在Lua中，几乎所有的东西都是围绕着lua_State转，所以，一般我们都会写一个类来封装管理它，比如：</p>
<pre class="brush: cpp;">
class LuaObject
{
public:
	LuaObject()
	{
		m_L = luaL_newstate();
		luaL_openlibs( m_L );
	}
	~LuaObject()
	{
		if ( m_L )
		{
			lua_close( m_L );
			m_L = NULL;
		}
	}

private:
	lua_State *m_L;
};
</pre>
<p>这很好，不过它不是指针安全的。试想，如果一个LuaObject对象被复制，结果将会怎样。</p>
<pre class="brush: cpp;">
LuaObject luaObject1;
LuaObject luaObject2( luaObject1 );
</pre>
<p>上面这段代码将会导致运行时crash，因为luaObject1和luaObject事实上指向了同一块lua_State，这样当luaObject1和luaObject2被析构时，lua_State会被两次lua_close，这不crash才怪呢！</p>
<p>事实是，当一个类包含了一个指针时，我们就需要开始变得格外谨慎，除了在构造函数和析构函数中要处理指针的初始化和清理外，我们还需要考虑深拷贝（deep copy），浅拷贝（shallow copy)）的问题。如果使用编译器默认生成的拷贝构造函数，它只会浅拷贝指针，而指针所指向的内存区域不会被拷贝。就像上面一样，两个LuaObject实则共享了一个lua_State。</p>
<p>那该如何处理让管理LuaObject类的指针安全呢，深拷贝？厄，首先我也没有深究深度拷贝lua_State具体该如何完成，不过我猜想这可是一个复杂而重型的操作，仅仅为了带来指针安全而选择此可不是一个明智的选择。</p>
<p>如果你是开发LuaObject类的程序员，也许你会对使用LuaObject的程序员（或许有时使用者就是你自己）说：“你不要对它进行拷贝操作不就OK了”，但这是一种严重不负责任的行为，因为这种皮球会越踢越远的。比如，程序员A使用了你的LuaObject类，他写了一个包含LuaObject的指针的类，同样A也不考虑拷贝指针安全问题，然后A又将它的类传递给了B，B封装了A的类指针，然后传递给了C，接着如此重复，C再给D，D再给E，最后E在对类进行拷贝操作时，程序crash掉了，因为在某个最底层，他们共享了lua_State。不过因为这时候已经嵌套了这么多层，E程序员或许根本不知道也不关心什么是LuaObject（他只跟D的类打交道）。这时，要想追踪到BUG之源——万恶的不考虑指针安全的LuaObject，已经非常困难了，God bless you all.</p>
<p>事实是，<strong>如果你不想让你的类被复制，你就应该明确而显示的禁止它</strong>。其实lua_State的这个问题非常类似于<em>Effective C++</em>书中的第14个条款中所提到的问题：在资源管理类中小心copying行为。对于这个问题，书中提供了两种解决方案。第一种就是<strong>禁止复制</strong>。第二种则是<strong>对底层资源的“引用计数法”（reference count）</strong>。</p>
<p>第一种禁止复制很简单。（关于<a href="http://www.bennychen.cn/?p=614">Uncopyable</a>）</p>
<pre class="brush: cpp;">
class LuaObject : private Uncopyable
{
public:
    ...
}
</pre>
<p>第二种则是使用智能指针来封装lua_State，我们可以使用boost的shared_ptr来封装lua_State，即shared_ptr< lua_State > m_L。如何对m_L进行初始化是另一个需要注意的问题，如果使用shared_ptr的常见初始化形式：m_L = shared_ptr< lua_State >( luaL_newstate() )，这样是不对的，因为在这种形式下，当lua_State的计数变为0时，shared_ptr会去调用lua_State的的析构函数，这显然是错误的，对lua_State的释放动作是lua_close而不是删除。事实上，这样编译器也无法通过，如果这么写，会报出“use of undefined type &#8216;lua_State&#8217;”的错误，提示lua_State是一个非完成的类型（incomplete type）。</p>
<p>我们应该为shared_ptr的初始化传入一个删除器（deleter）。很显然，lua_State的deleter是lua_close()函数，这样最终的代码如下。</p>
<pre class="brush: cpp;">
#include &lt;boost/shared_ptr.hpp&gt;
using boost::shared_ptr;

class LuaObject
{
public:
	LuaObject()
	{
		m_L = shared_ptr&lt; lua_State &gt;( luaL_newstate(), lua_close );
		luaL_openlibs( m_L.get() );
	}

private:
	shared_ptr&lt; lua_State &gt; m_L;
};
</pre>
<p>这样再回到前面拷贝的那个例子，luaObject1和luaObject2共同引用了一个lua_State，但因为使用了shared_ptr，所以只有在lua_State的引用次数变为0时，它的deleter（这里是lua_close）才会被调用，安全了！</p>
<p>在我的项目中，因为没有使用boost库，也没有提供任何智能指针，所以使用禁止复制来保证安全。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=976</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>上周围观巴萨的片片</title>
		<link>http://www.bennychen.cn/?p=947</link>
		<comments>http://www.bennychen.cn/?p=947#comments</comments>
		<pubDate>Sat, 14 Aug 2010 04:39:37 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Visca Barça]]></category>
		<category><![CDATA[Asia tour]]></category>
		<category><![CDATA[barca]]></category>
		<category><![CDATA[Beijing]]></category>
		<category><![CDATA[鸟巢]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=947</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450477022.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-948" title="赛前训练" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450477022-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_453034758.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-950" title="fabulous 4" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_453034758-300x199.jpg" alt="" width="300" height="199" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451274734.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-951" title="waving flag" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451274734-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450468579.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-952" title="3人行" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450468579-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450467793.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-953" title="my back" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1074892_450467793-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297431.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-954" title="Messi! Messi!" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297431-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297538.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-955" title="Messi is dribling" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297538-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297635.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-956" title="Game is kicking off~" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451297635-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304466.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-957" title="Cops &amp; Barca's substitution " src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304466-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304560.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-958" title="Messi's free kick" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304560-300x200.jpg" alt="" width="300" height="200" /></a><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304623.jpg" class="highslide-image" onclick="return hs.expand(this);"></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304623.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-959" title="Guoan's free kick in box" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304623-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304686.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-960" title="Game is kicking off" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304686-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304751.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-961" title="Unstoppable Messi" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451304751-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451305967.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="alignnone size-medium wp-image-962" title="Ibra! Goal!" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/1076629_451305967-300x200.jpg" alt="" width="300" height="200" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=947</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What a day!</title>
		<link>http://www.bennychen.cn/?p=942</link>
		<comments>http://www.bennychen.cn/?p=942#comments</comments>
		<pubDate>Sat, 07 Aug 2010 15:48:48 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Visca Barça]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=942</guid>
		<description><![CDATA[今天去了工体，因为晚上有巴萨的训练。本来有机会可以让媒体带进去的，但是在最后时刻还是把机会让给了好友。只能感到非常的遗憾了，很多年才有这么一次机会，那些热爱的球星与自己只有一墙之隔，却只能在场外感叹唏嘘。巴萨来到北京已经好几天了，而我最近的状态几乎是被工作所淹没了，作为一个绝对的巴萨死忠，这次中国行似乎跟自己没有半毛钱关系，我真的是老了么&#8230; 当巴萨的大巴到达体育场外时，我奔跑着追逐到了梅西的脸庞，爬在工体的铁门上，我远远的望到了伊布的身影，这就是我今天所有追逐的收获。那一刻，觉得他们距离自己是那么的接近，却突然又感觉如此的遥远。但，作为亿万巴萨球迷之一，这已是一种莫大的幸福。 明天，鸟巢见。 Visca Barca]]></description>
			<content:encoded><![CDATA[<p>今天去了工体，因为晚上有巴萨的训练。本来有机会可以让媒体带进去的，但是在最后时刻还是把机会让给了好友。只能感到非常的遗憾了，很多年才有这么一次机会，那些热爱的球星与自己只有一墙之隔，却只能在场外感叹唏嘘。巴萨来到北京已经好几天了，而我最近的状态几乎是被工作所淹没了，作为一个绝对的巴萨死忠，这次中国行似乎跟自己没有半毛钱关系，我真的是老了么&#8230;</p>
<p>当巴萨的大巴到达体育场外时，我奔跑着追逐到了梅西的脸庞，爬在工体的铁门上，我远远的望到了伊布的身影，这就是我今天所有追逐的收获。那一刻，觉得他们距离自己是那么的接近，却突然又感觉如此的遥远。但，作为亿万巴萨球迷之一，这已是一种莫大的幸福。</p>
<p>明天，鸟巢见。</p>
<p>Visca Barca</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=942</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>革命的雨</title>
		<link>http://www.bennychen.cn/?p=936</link>
		<comments>http://www.bennychen.cn/?p=936#comments</comments>
		<pubDate>Fri, 06 Aug 2010 14:57:51 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Something In The Way]]></category>
		<category><![CDATA[革命的雨]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=936</guid>
		<description><![CDATA[上周我给我哥也整了个Wordpress个人博客，前后断断续续折腾了差不多一个星期，博客地址是： http://www.xiaoyong.me 我哥已经零星的贴了一些闲暇时画的东西——革命的雨，他是我爱的兄长，是我从小膜拜的偶像，是一位才华横溢的绝对天才。 另外感谢小行同学慷慨提供的超大主机空间，you are awesome，嗯哼~]]></description>
			<content:encoded><![CDATA[<p>上周我给我哥也整了个Wordpress个人博客，前后断断续续折腾了差不多一个星期，博客地址是：</p>
<p><a href="http://www.xiaoyong.me" target="_blank">http://www.xiaoyong.me</a></p>
<p>我哥已经零星的贴了一些闲暇时画的东西——革命的雨，他是我爱的兄长，是我从小膜拜的偶像，是一位才华横溢的绝对天才。</p>
<p>另外感谢小行同学慷慨提供的超大主机空间，you are awesome，嗯哼~</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=936</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome, Barca! Farewell, Rafa.</title>
		<link>http://www.bennychen.cn/?p=928</link>
		<comments>http://www.bennychen.cn/?p=928#comments</comments>
		<pubDate>Mon, 02 Aug 2010 15:11:05 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Visca Barça]]></category>
		<category><![CDATA[barca]]></category>
		<category><![CDATA[北京]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=928</guid>
		<description><![CDATA[巴萨要来了？是真的！ 不过这次因为世界杯，西班牙国家队的八大成员都将不会前来，甚至连期待的拉马西亚的两孩子博扬和赫弗伦都不来了，来京阵容已经严重缩水。虽然如此，随着离8月8号的日益临近，还是忍不住越来越激动。 不过这次我也就只能去看场比赛而已了，什么接机，蹲酒店这类的事我已经干不了了，老了，不能像3年前那样了。 瓜帅，梅西，周末鸟巢见！ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- Marquez走了，这位在巴萨效力了7年的墨西哥队长最终告别了诺坎谱。七年，小马哥已经变成了老马哥，当年的长发也已削去，但他的足球故事还将继续，他将在另外一块球场继续谱写他的墨西哥传奇。他说他会一辈子爱巴萨，巴萨是他一生的俱乐部，我们也会一直热爱你。别了，Rafa。]]></description>
			<content:encoded><![CDATA[<p>巴萨要来了？是真的！</p>
<p>不过这次因为世界杯，西班牙国家队的八大成员都将不会前来，甚至连期待的拉马西亚的两孩子博扬和赫弗伦都不来了，来京阵容已经严重缩水。虽然如此，随着离8月8号的日益临近，还是忍不住越来越激动。</p>
<p>不过这次我也就只能去看场比赛而已了，什么接机，蹲酒店这类的事我已经干不了了，老了，不能像<a href="http://blog.sina.com.cn/s/blog_3f82386d010009ay.html">3年前</a>那样了。</p>
<p>瓜帅，梅西，周末鸟巢见！</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/2010-07-31_ENTREVISTA_RAFA_MARQUEZ_010.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="size-full wp-image-933 alignright" title="Rafa Marquez" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/08/2010-07-31_ENTREVISTA_RAFA_MARQUEZ_010.jpg" alt="" width="198" height="150" /></a>Marquez走了，这位在巴萨效力了7年的墨西哥队长最终告别了诺坎谱。七年，小马哥已经变成了老马哥，当年的长发也已削去，但他的足球故事还将继续，他将在另外一块球场继续谱写他的墨西哥传奇。他说他会一辈子爱巴萨，巴萨是他一生的俱乐部，我们也会一直热爱你。别了，Rafa。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=928</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Onine Courses</title>
		<link>http://www.bennychen.cn/?p=903</link>
		<comments>http://www.bennychen.cn/?p=903#comments</comments>
		<pubDate>Sun, 01 Aug 2010 13:19:14 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Some Experiences]]></category>
		<category><![CDATA[MIT]]></category>
		<category><![CDATA[Stanford]]></category>
		<category><![CDATA[在线课程]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=903</guid>
		<description><![CDATA[第一次听说online course是同事给我推荐的MIT的讲algorithm的课程，随后自己上youtube看了几集，真是大赞。并不是说崇洋，而是国外的老师确实讲得好，条理清晰，而且不乏个人风格，幽默风趣。更难得的，计算机的课程他们居然都是全部只用黑板，而很少用slides。并不是说slides不好，而是他们不像国内的老师，讲课通篇都是过PPT，发催眠曲。online course真是个好东西，让我们这些土鳖能够不用留洋就能感受到国外计算机的课程，况且还是像MIT，Stanford这样的名校。通过这些课程，不仅能领略到国外老师的风采，还能学英语，因为如果听不懂，有些课程还配置了整个课程的transcript，真是非常优质的学习材料。 不过这些课程，对于我这样的已经走出学校的人来说，只能粗看感受一下精华了，不可能真的跟着课程一集一集的细嚼慢咽，已经过了全额学习的那个时期了，要是早几年在大学里能发现这样的材料就好了（或许那时候也没有）。 http://see.stanford.edu/see/courses.aspx Stanford的关于computer science的课程，课程不多，但都非常详细完整的提供了video, handout, assignment, transcript，甚至还有考试试题和答案。 http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/ MIT的，课程很丰富，但只有部分提供了video，推荐Introduction to Algorithms.]]></description>
			<content:encoded><![CDATA[<p>第一次听说online course是同事给我推荐的MIT的讲algorithm的课程，随后自己上youtube看了几集，真是大赞。并不是说崇洋，而是国外的老师确实讲得好，条理清晰，而且不乏个人风格，幽默风趣。更难得的，计算机的课程他们居然都是全部只用黑板，而很少用slides。并不是说slides不好，而是他们不像国内的老师，讲课通篇都是过PPT，发催眠曲。online course真是个好东西，让我们这些土鳖能够不用留洋就能感受到国外计算机的课程，况且还是像MIT，Stanford这样的名校。通过这些课程，不仅能领略到国外老师的风采，还能学英语，因为如果听不懂，有些课程还配置了整个课程的transcript，真是非常优质的学习材料。</p>
<p>不过这些课程，对于我这样的已经走出学校的人来说，只能粗看感受一下精华了，不可能真的跟着课程一集一集的细嚼慢咽，已经过了全额学习的那个时期了，要是早几年在大学里能发现这样的材料就好了（或许那时候也没有）。</p>
<p><a href="http://see.stanford.edu/see/courses.aspx" target="_blank">http://see.stanford.edu/see/courses.aspx</a></p>
<p>Stanford的关于computer science的课程，课程不多，但都非常详细完整的提供了video, handout, assignment, transcript，甚至还有考试试题和答案。</p>
<p><a href="http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/" target="_blank">http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/</a></p>
<p>MIT的，课程很丰富，但只有部分提供了video，推荐<a href="http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005"><span style="text-decoration: underline;">Introduction to Algorithms</span></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=903</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>走着</title>
		<link>http://www.bennychen.cn/?p=879</link>
		<comments>http://www.bennychen.cn/?p=879#comments</comments>
		<pubDate>Mon, 26 Jul 2010 13:51:21 +0000</pubDate>
		<dc:creator>Benny</dc:creator>
				<category><![CDATA[Something In The Way]]></category>

		<guid isPermaLink="false">http://www.bennychen.cn/?p=879</guid>
		<description><![CDATA[2010年7月6日，我二十年的学生生涯正式宣告结束；2010年7月6日，我的职业生涯的第一天开始了。 那天我是早晨9点从学校拿到的毕业和学位的证书，随后便打了车直奔公司，参加11：30的入职仪式。没有片刻的休息，我的人生的两大阶段间的分隔符仅用了两个小时便匆匆划完。 虽然匆忙，但这短短的数星期的时间，却划过了我人生最精彩的篇章，一切就像是电影一样。从新家的入住，到正式的毕业，从离开学校到跨入公司，中间还伴随着世界杯的精彩，有章鱼大帝的威武，有美丽西班牙的称霸，而最近我又度过了自己24周岁的生日。这真是一个收获的时节哇，但我却来不及驻足片刻来细细品味其中的甜蜜，因为人生驱赶着我们不断前行，一个终点只是下一段路程的起点而已。不管是苦是甜，让我们记录下这一个个精彩而幸福的瞬间，人生便无憾。 走着。 At China National Film Museum, July, 2010]]></description>
			<content:encoded><![CDATA[<p>2010年7月6日，我二十年的学生生涯正式宣告结束；2010年7月6日，我的职业生涯的第一天开始了。</p>
<p>那天我是早晨9点从学校拿到的毕业和学位的证书，随后便打了车直奔公司，参加11：30的入职仪式。没有片刻的休息，我的人生的两大阶段间的分隔符仅用了两个小时便匆匆划完。</p>
<p>虽然匆忙，但这短短的数星期的时间，却划过了我人生最精彩的篇章，一切就像是电影一样。从新家的入住，到正式的毕业，从离开学校到跨入公司，中间还伴随着世界杯的精彩，有章鱼大帝的威武，有美丽西班牙的称霸，而最近我又度过了自己24周岁的生日。这真是一个收获的时节哇，但我却来不及驻足片刻来细细品味其中的甜蜜，因为人生驱赶着我们不断前行，一个终点只是下一段路程的起点而已。不管是苦是甜，让我们记录下这一个个精彩而幸福的瞬间，人生便无憾。</p>
<p>走着。</p>
<p><a href="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/07/72CC2AE60C524B0C155E1C6C754D00AD_800.jpg" class="highslide-image" onclick="return hs.expand(this);"><img class="size-full wp-image-885 alignnone" title="at National Film Museum" src="http://www.bennychen.cn/wordpress/wp-content/uploads/2010/07/72CC2AE60C524B0C155E1C6C754D00AD_800.jpg" alt="" width="346" height="230" /></a></p>
<p style="font-size: x-small;">At China National Film Museum, July, 2010</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bennychen.cn/?feed=rss2&amp;p=879</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
