﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-路的尽头-文章分类-库／框架</title><link>http://www.cppblog.com/tangxinfa/category/5923.html</link><description>开发者之旅</description><language>zh-cn</language><lastBuildDate>Tue, 28 Feb 2012 09:34:50 GMT</lastBuildDate><pubDate>Tue, 28 Feb 2012 09:34:50 GMT</pubDate><ttl>60</ttl><item><title>node.js tips</title><link>http://www.cppblog.com/tangxinfa/articles/nodejs_tips.html</link><dc:creator>唐新发</dc:creator><author>唐新发</author><pubDate>Sat, 18 Feb 2012 04:25:00 GMT</pubDate><guid>http://www.cppblog.com/tangxinfa/articles/nodejs_tips.html</guid><wfw:comment>http://www.cppblog.com/tangxinfa/comments/165904.html</wfw:comment><comments>http://www.cppblog.com/tangxinfa/articles/nodejs_tips.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tangxinfa/comments/commentRss/165904.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tangxinfa/services/trackbacks/165904.html</trackback:ping><description><![CDATA[A. 使用sudo npm -g install xxx安装的全局包在require时提示找不到。<br />Q. 在项目根目录下执行sudo npm link xxx即可。<br /><img src ="http://www.cppblog.com/tangxinfa/aggbug/165904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tangxinfa/" target="_blank">唐新发</a> 2012-02-18 12:25 <a href="http://www.cppblog.com/tangxinfa/articles/nodejs_tips.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Protocol Buffer学习笔记</title><link>http://www.cppblog.com/tangxinfa/articles/87022.html</link><dc:creator>唐新发</dc:creator><author>唐新发</author><pubDate>Sun, 07 Jun 2009 15:02:00 GMT</pubDate><guid>http://www.cppblog.com/tangxinfa/articles/87022.html</guid><wfw:comment>http://www.cppblog.com/tangxinfa/comments/87022.html</wfw:comment><comments>http://www.cppblog.com/tangxinfa/articles/87022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tangxinfa/comments/commentRss/87022.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tangxinfa/services/trackbacks/87022.html</trackback:ping><description><![CDATA[　　一直在寻找c++的自动序列化库，希望能够自动生成序列化代码，像ICE、gSoap都有实现。gSoap主要是它只能序列化成基于xml的soap格式数据；而ICE好是好，可惜吃不起。最近有朋友推荐<a href="http://code.google.com/apis/protocolbuffers/">Protocol Buffer</a>，这个东西基本上附合我的要求，可以序列化成高效的二进制格式，如果能够提供序列化成文本（如：XML)的功能，会便于调试。<br />手册上有一段话初看让人疑惑：<br /><strong>Protocol Buffers and O-O Design</strong> Protocol buffer
classes are basically dumb data holders (like structs in C++); they
don't make good first class citizens in an object model. If you want to
add richer behaviour to a generated class, the best way to do this is
to wrap the generated protocol buffer class in an application-specific
class. Wrapping protocol buffers is also a good idea if you don't have
control over the design of the <code>.proto</code> file (if, say,
you're reusing one from another project). In that case, you can use the
wrapper class to craft an interface better suited to the unique
environment of your application: hiding some data and methods, exposing
convenience functions, etc. <strong>You should never add behaviour to the generated classes by inheriting from them</strong>. This will break internal mechanisms and is not good object-oriented practice anyway.

<br />大意是不要从它生成的Message类进行派生，以便加入一些行为函数，而应该采用包装（wrap）的方式，说白了就是组合（在你的类中放一个生成的Message类成员变量）。通过查看邮件列表，载录以下详细解释：<br />　*如果进行派生，那么你的类中会混入Protocol Buffer生成的一些方法，而这些方法将来还可能会变化，<br />　这就意味着你的类将依赖Protocol Buffer的实现。用设计相关的术语就是：你继承了实现，你把业务和数据混在了一起。<br /><img src ="http://www.cppblog.com/tangxinfa/aggbug/87022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tangxinfa/" target="_blank">唐新发</a> 2009-06-07 23:02 <a href="http://www.cppblog.com/tangxinfa/articles/87022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gsoap学习笔记</title><link>http://www.cppblog.com/tangxinfa/articles/78344.html</link><dc:creator>唐新发</dc:creator><author>唐新发</author><pubDate>Mon, 30 Mar 2009 02:37:00 GMT</pubDate><guid>http://www.cppblog.com/tangxinfa/articles/78344.html</guid><wfw:comment>http://www.cppblog.com/tangxinfa/comments/78344.html</wfw:comment><comments>http://www.cppblog.com/tangxinfa/articles/78344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tangxinfa/comments/commentRss/78344.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tangxinfa/services/trackbacks/78344.html</trackback:ping><description><![CDATA[1，stub和skeleton是什么？做什么用的？<br />　　它们是自动实现了的函数。<br />　　stub由client使用，skeleton由server在收到请求时自动调用。<br />　　考虑最基本的通信：client-&gt;network-&gt;server<br />　　在network的两个边界分别就是stub和skeleton<br />　　gsoap通过生成stub和skeleton，让我们的client只需调用一下stub函数，而server只需要实现skeleton函数内部调用的对应的处理函数。<br /><img src ="http://www.cppblog.com/tangxinfa/aggbug/78344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tangxinfa/" target="_blank">唐新发</a> 2009-03-30 10:37 <a href="http://www.cppblog.com/tangxinfa/articles/78344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4cxx使用心得</title><link>http://www.cppblog.com/tangxinfa/articles/log4cxx_tips.html</link><dc:creator>唐新发</dc:creator><author>唐新发</author><pubDate>Tue, 17 Jun 2008 02:01:00 GMT</pubDate><guid>http://www.cppblog.com/tangxinfa/articles/log4cxx_tips.html</guid><wfw:comment>http://www.cppblog.com/tangxinfa/comments/53660.html</wfw:comment><comments>http://www.cppblog.com/tangxinfa/articles/log4cxx_tips.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tangxinfa/comments/commentRss/53660.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tangxinfa/services/trackbacks/53660.html</trackback:ping><description><![CDATA[
		<ul>
		</ul>
		<ul>
				<li>简介</li>
		</ul>apache出品必属精品。正宗c++日志库，与log4j一脉相承。<br /><a href="http://logging.apache.org/log4cxx/index.html">http://logging.apache.org/log4cxx/index.html</a><ul><li>下载、编译、安装</li></ul>打算安装到${HOME}/libs目录下：<br /><i>cd ~/libs<br />wget http://mirror.bjtu.edu.cn/apache//apr/apr-1.4.4.tar.bz2<br />tar xjvf apr-1.4.4.tar.bz2<br />cd apr-1.4.4<br />./configure --prefix=${HOME}/libs &amp;&amp; make &amp;&amp; make install<br />cd ..<br />wget http://mirror.bjtu.edu.cn/apache//apr/apr-util-1.3.11.tar.bz2<br />tar xjvf apr-util-1.3.11.tar.bz2<br />cd apr-util-1.3.11<br />./configure --prefix=${HOME}/libs --with-apr=${HOME}/libs &amp;&amp; make &amp;&amp; make install<br />cd ..<br />wget http://apache.etoak.com//logging/log4cxx/0.10.0/apache-log4cxx-0.10.0.tar.gz<br />tar xzvf </i><i>apache-log4cxx-0.10.0.tar.gz</i><i><br />cd apache-log4cxx-0.10.0<br />./configure --with-charset=utf-8 --prefix=${HOME}/libs --with-apr=${HOME}/libs --with-apr-util=${HOME}/libs &amp;&amp; make &amp;&amp; make install</i><br /><br /><ul><li>使用例子</li></ul>hello.cpp:<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">log4cxx/logger.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">log4cxx/propertyconfigurator.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">hello</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> argc, </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">argv[])<br />{<br />        log4cxx::PropertyConfigurator::configure(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">./log4cxx_hello.properties</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        LOG4CXX_INFO(logger, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">你好，log4cxx!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br />log4cxx_hello.properties:<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">log4j.rootLogger</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">debug</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> R<br /><br />log4j.appender.stdout</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">org.apache.log4j.ConsoleAppender<br />log4j.appender.stdout.layout</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">org.apache.log4j.PatternLayout<br /><br /># Pattern to output the caller's file name and line number.<br />log4j.appender.stdout.layout.ConversionPattern</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">%5p </span><span style="color: rgb(128, 0, 0); font-weight: bold;">[</span><span style="color: rgb(128, 0, 0);">%t</span><span style="color: rgb(128, 0, 0); font-weight: bold;">]</span><span style="color: rgb(0, 0, 0);"> (%F:%L) - %m%n<br /><br />log4j.appender.R</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">org.apache.log4j.RollingFileAppender<br />log4j.appender.R.File</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">./hello.log<br /><br />log4j.appender.R.MaxFileSize</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">100KB<br /># Keep one backup file<br />log4j.appender.R.MaxBackupIndex</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);"><br /><br />log4j.appender.R.layout</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">org.apache.log4j.PatternLayout<br />log4j.appender.R.layout.ConversionPattern</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">%5p %c </span><span style="color: rgb(128, 0, 0); font-weight: bold;">[</span><span style="color: rgb(128, 0, 0);">%t</span><span style="color: rgb(128, 0, 0); font-weight: bold;">]</span><span style="color: rgb(0, 0, 0);"> (%F:%L) - %m%n<br /></span></div><br /><i>g++ -o hello hello.cpp -I${HOME}/libs/include ${HOME}/libs/lib/liblog4cxx.a </i><i>${HOME}/libs/lib/libaprutil-1.a</i><i> ${HOME}/libs/lib/libapr-1.a  -lexpat</i> -lpthread<br /><br /><ul><li>注意事项</li></ul>1，配置的MaxBackupIndex不得过大，log4cxx编译时限制了它的大小（大概十多个），一个日志文件写满后会重命名所有已有的日志文件，<br />这个限制避免性能问题，可以通过设置大一点的MaxFileSize来保存更多日志，否则就要在编译时改大一点了。<br />参考：http://objectmix.com/apache/684503-urgent-log4cxx-large-window-sizes-not-allowed.html<br /><br /><ul><li>使用技巧</li></ul>1，决定配置文件的格式（xml，property）。以使用相应的配置器（Configurator）装入配置文件。<br />     xml虽较property格式繁锁，支持的配置面更全，而property格式的配置文件使用更简单，容易在网上找到现成的配置文件。<br />2，logger命名。<br />     logger名称反映了软件模块，如果有代表软件模块的类，则在类中包含以该类类名命名的logger对象，该模块功能相关代码通过该logger进行日志记录。<br />另外可将logger对象作为全局变量，方便使用，特别是当软件模块较松散，并无对应的封装类时。<br />3，在代码中适当地放置日志代码。引用适当的日志对象，对日志进行适当分级。<br />4，余下的工作就是修改配置文件，对日志进行控制了。<br />　　使用配置文件的好处就是可以方便地配置日志而不需要修改源代码，可以在配置文件中方便配置日志过滤、格式、日志目的地。<br /><br /><ul><li>体验</li></ul>　　之前产品中用到的是log4cplus，但是常常有写日志崩溃的情况出现，使用log4cxx正是用于解决该崩溃。<br /><img src ="http://www.cppblog.com/tangxinfa/aggbug/53660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tangxinfa/" target="_blank">唐新发</a> 2008-06-17 10:01 <a href="http://www.cppblog.com/tangxinfa/articles/log4cxx_tips.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>