﻿<?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++博客-Kyee编程之道-文章分类-C++类库KYLib </title><link>http://www.cppblog.com/kyee/category/16948.html</link><description>程序员应该脚踏实地，切忌心浮气燥。</description><language>zh-cn</language><lastBuildDate>Mon, 23 May 2011 01:01:19 GMT</lastBuildDate><pubDate>Mon, 23 May 2011 01:01:19 GMT</pubDate><ttl>60</ttl><item><title>快速压缩/解压缩类源码</title><link>http://www.cppblog.com/kyee/articles/146917.html</link><dc:creator>Kyee Ye</dc:creator><author>Kyee Ye</author><pubDate>Sun, 22 May 2011 04:24:00 GMT</pubDate><guid>http://www.cppblog.com/kyee/articles/146917.html</guid><wfw:comment>http://www.cppblog.com/kyee/comments/146917.html</wfw:comment><comments>http://www.cppblog.com/kyee/articles/146917.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyee/comments/commentRss/146917.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyee/services/trackbacks/146917.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: TKYQuickPack(快速压缩类), TKYQuickUnpack(快速解压缩类), 源码如下: KYQuickPack.h 文件Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->&nbsp;1&nbsp;//&nbsp;==========...&nbsp;&nbsp;<a href='http://www.cppblog.com/kyee/articles/146917.html'>阅读全文</a><img src ="http://www.cppblog.com/kyee/aggbug/146917.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyee/" target="_blank">Kyee Ye</a> 2011-05-22 12:24 <a href="http://www.cppblog.com/kyee/articles/146917.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用AVLtree实现 map 类模板源码</title><link>http://www.cppblog.com/kyee/articles/146916.html</link><dc:creator>Kyee Ye</dc:creator><author>Kyee Ye</author><pubDate>Sun, 22 May 2011 04:10:00 GMT</pubDate><guid>http://www.cppblog.com/kyee/articles/146916.html</guid><wfw:comment>http://www.cppblog.com/kyee/comments/146916.html</wfw:comment><comments>http://www.cppblog.com/kyee/articles/146916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyee/comments/commentRss/146916.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyee/services/trackbacks/146916.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->&nbsp;&nbsp;1&nbsp;//&nbsp;=======================================&nbsp;&nbsp;2&nbsp;//&nbsp;Unit&nbsp...&nbsp;&nbsp;<a href='http://www.cppblog.com/kyee/articles/146916.html'>阅读全文</a><img src ="http://www.cppblog.com/kyee/aggbug/146916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyee/" target="_blank">Kyee Ye</a> 2011-05-22 12:10 <a href="http://www.cppblog.com/kyee/articles/146916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>String 替换函数源码</title><link>http://www.cppblog.com/kyee/articles/146915.html</link><dc:creator>Kyee Ye</dc:creator><author>Kyee Ye</author><pubDate>Sun, 22 May 2011 04:05:00 GMT</pubDate><guid>http://www.cppblog.com/kyee/articles/146915.html</guid><wfw:comment>http://www.cppblog.com/kyee/comments/146915.html</wfw:comment><comments>http://www.cppblog.com/kyee/articles/146915.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyee/comments/commentRss/146915.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyee/services/trackbacks/146915.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: --------------------------------------------------------------------------------标题: String 替换函数源码作者: 叶飞虎日期: 2010.03.15--------------------------------------------------------------------------------...&nbsp;&nbsp;<a href='http://www.cppblog.com/kyee/articles/146915.html'>阅读全文</a><img src ="http://www.cppblog.com/kyee/aggbug/146915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyee/" target="_blank">Kyee Ye</a> 2011-05-22 12:05 <a href="http://www.cppblog.com/kyee/articles/146915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Win32平台中，多读单写锁如何实现？</title><link>http://www.cppblog.com/kyee/articles/146910.html</link><dc:creator>Kyee Ye</dc:creator><author>Kyee Ye</author><pubDate>Sun, 22 May 2011 03:22:00 GMT</pubDate><guid>http://www.cppblog.com/kyee/articles/146910.html</guid><wfw:comment>http://www.cppblog.com/kyee/comments/146910.html</wfw:comment><comments>http://www.cppblog.com/kyee/articles/146910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyee/comments/commentRss/146910.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyee/services/trackbacks/146910.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: --------------------------------------------------------------------------------标题: 在Win32平台中，多读单写锁如何实现？作者: 叶飞虎日期: 2004.03.17---------------------------------------------------------------------------...&nbsp;&nbsp;<a href='http://www.cppblog.com/kyee/articles/146910.html'>阅读全文</a><img src ="http://www.cppblog.com/kyee/aggbug/146910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyee/" target="_blank">Kyee Ye</a> 2011-05-22 11:22 <a href="http://www.cppblog.com/kyee/articles/146910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 代码移植要点</title><link>http://www.cppblog.com/kyee/articles/146904.html</link><dc:creator>Kyee Ye</dc:creator><author>Kyee Ye</author><pubDate>Sun, 22 May 2011 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/kyee/articles/146904.html</guid><wfw:comment>http://www.cppblog.com/kyee/comments/146904.html</wfw:comment><comments>http://www.cppblog.com/kyee/articles/146904.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyee/comments/commentRss/146904.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyee/services/trackbacks/146904.html</trackback:ping><description><![CDATA[<p>--------------------------------------------------------------------------------<br />标题: C++ 代码移植要点<br />作者: 叶飞虎<br />日期: 2010.09.06<br />--------------------------------------------------------------------------------</p>
<p>1. 分层设计<br />&nbsp;&nbsp; 隔离平台相关的代码, 就像可测试性一样, 可移植性也要从设计抓起。一般来说, 最上<br />&nbsp;&nbsp; 层和最下层都不具有良好的可移植性:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1). 最上层是 GUI, 大多数 GUI 都不是跨平台的, 如: Win32 SDK 和 MFC<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2). 最下层是操作系统 API, 大部分操作系统 API 都是专用的</p>
<p>&nbsp;&nbsp; 如果这两层的代码散布在整个软件中, 那么这个软件的可植性将非常的差, 这是不言自<br />&nbsp;&nbsp; 明的。那么如何避免这种情况呢? 当然是分层设计了:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1). 最底层采用 Adapter 模式, 把不同操作系统的 API 封装成一套统一的接口(如:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KYLib 库), 至于封装成类还是封装成函数, 要看实际情况而定。如果在开发第<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个平台时就采用 KYLib, 可以大大减少移植的工作量。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2). 最上层采用分离界面表现与内部逻辑代码的模式, 把大部分代码放到内部逻辑里<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 面, 界面仅仅是显示和接收输入, 即使要换一套 GUI, 工作量也不大。这同时也<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 是提高可测试性的手段之一, 当然还有其它一些附加好处。所以即使你采用 QT<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 或者 GTK+ 等跨平台的 GUI 设计软件界面, 分离界面表现与内部逻辑也是非常<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有用的。</p>
<p><br />2. 注意平台的特性<br />&nbsp;&nbsp; a. 目录分隔符: 在Windows下用 '\\', 在Linux下用 '/'。</p>
<p>&nbsp;&nbsp; b. 文本文件换行符: 在Windows下用 "\r\n", 在Linux下用 '\n'。</p>
<p>&nbsp;&nbsp; c. 在 Windows 中文件名不区分大小写字母, 而在 Linux 中则区分大小写字母。</p>
<p>&nbsp;&nbsp; d. 在 Windows 中线程可以 suspend 和 resume, 而在 Linux 中则不允许此操作。</p>
<p>&nbsp;&nbsp; e. 在 Windows 的动态库中, 除非明确指明为 export 的函数外, 其它函数对外都是不<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可见的。</p>
<p>&nbsp;&nbsp; f. 在 Linux 的共享库中, 所有非 static 的全局变量和函数, 对外全部是可见的。这<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要特别小心, 同名函数引起的问题, 让你查上两天也不为过。</p>
<p>&nbsp;&nbsp; g. 在 Linux 的共享库中, 如果想绑定共享库里的全局符号(变量, 函数和类等等), 则<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在链接共享库的时候, 添加 gcc 选项 -Wl,-Bsymbolic 即可。</p>
<p>&nbsp;&nbsp; h. 在 Linux 的共享库中, 如果共享库存取主程序里定义的全局符号, 链接主程序的时<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 候, 使用参数 -Wl,--export-dynamic 即可。</p>
<p><br />3. 最好不要使用编译器特有的特性<br />&nbsp;&nbsp; a. 像在 VC 里, 你要实现线程局部存储, 在变量前加一个 __declspec( thread ) 就行<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 了, 然而尽管在 pthread 里有类似的功能, 却不能按这种方式实现, 所以无法移植<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 到 Linux 下。</p>
<p>&nbsp;&nbsp; b. 同样 gcc 也有很多扩展, 是在 VC 或者其它编译器里所没有的。如编译成多线程安<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 全的选项 -pthread, 此选项在编译源程序和链接时使用。</p>
<p><br />4. 数据类型差别<br />&nbsp;&nbsp; a. 在 VC 中64位整型是 __int64, 而在 Linux 中是 int64_t。</p>
<p>&nbsp;&nbsp; b. 在 VC 中函数指针默认情况下可以直接赋值给 void* 类型变量, 而在 Linux 中则不<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 允许直接赋值, 必须使用 (void*) 强制转换。</p>
<p>&nbsp;&nbsp; c. 在 Windows 中的原子锁相关函数 InterlockXXX 中的参数类型是 long*,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而在 Linux 中参数类型是 int*。</p>
<p><br />5. 调用外部库(静态库和动态库)差异<br />&nbsp;&nbsp; a. 在 VC 中调用外部库有 .lib 支持, 若是动态库则直接通过 .lib 关联。</p>
<p>&nbsp;&nbsp; b. 在 Linux 中调用静态库为 .a 文件, 库之间的先后顺序非常重要, 如 libKYLib.a<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和 libkylin.a, 且 kylin 依赖 KYLib, 则在工程中加载库的顺序必须为: 先加载<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libkylin.a, 再加载 libKYLib.a。</p>
<p>&nbsp;&nbsp; c. 在 Linux 中调用动态库为 .so 文件, 如果有好几个库, 它们之间有一些依赖关系的<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 话, 例如 X 依赖 Y, 那么你就要先加载那些被依赖的 Y, 然后加载 X。</p>
<p>&nbsp;&nbsp; d. 在 Linux 中混合调用静态库和动态库, 如使用 libKYLib.a 和 libswgci32c.so, 且<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libswgci32c.so 中使用了 libKYLib.a, 则在加载库时必须先加载 libKYLib.a, 然<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后再加载 libswgci32c.so。</p>
<p><br />6. 加载动态库时查找路径顺序的差异<br />&nbsp;&nbsp; a. Windows 库搜索路径和顺序<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1). 应用程序目录<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2). 当前工作目录<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3). 系统目录 (%systemroot%, %systemroot%\system 和 %systemroot%\system32),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如: C:\WINNT\, C:\WINNT\system, C:\WINNT\system32<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4). 路径变量 (系统的环境变量 Path)</p>
<p>&nbsp;&nbsp; b. Linux 库搜索路径和顺序<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1). 链接时指定的路径, 如: -Wl,-rpath=./ 选项表示编译时 ld 路径<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2). 环境变量 LD_LIBRARY_PATH 指明的路径<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3). /etc/ld.so.cache中的函数库列表<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4). /lib目录, 然后/usr/lib<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5). 当前工作目录</p>
<p><br />7. 动态库入口函数的差异<br />&nbsp;&nbsp; a. Windows 中有 DllMain 入口函数, 而 Linux 中则没有。</p>
<p>&nbsp;&nbsp; b. Linux 中有特殊函数 _init 和 _fini, 主要是分别用来初始化函数库和关闭的时候<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 做一些必要的处理, 我们可以把自己认为需要的代码放到这两个函数里面, 它们分别<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在函数库被加载和释放的时候被执行。具体说, 如果一个函数库里面有一个名字为<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_init" 的函数输出, 那么在第一次通过 dlopen() 函数打开这个函数库, 或者只是<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 简单的作为共享函数库被打开的时候, _init 函数被自动调用执行。与之相对应的就<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 是 _fini 函数, 当一个程序调用 dlclose() 去释放对这个函数库的引用的时候, 如<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 果该函数库的被引用计数器为 0 了, 或者这个函数库是作为一般的共享函数库被使<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用而使用它的程序正常退出的时候, _fini就会被调用执行。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C语言定义它们的原型如下：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void _init(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void _fini(void);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当使用你自己的 _init 和 _fini 函数时, 会出现命名冲突, 就会得到一个<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "multiple-definition" 的错误, 编译器提示已经存在这个名字, 可以通过几种方式<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来解决：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1). 自定义 init 函数名字, 比如 myinit 用 -Wl, 选项给 ld 传递此名字:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc ... -Wl,-init=myinit</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2). 当 GCC 编译源程序时, 可以使用选项 -nostartfiles 来使共享库不与系统<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 启动文件一起编译<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc ... -nostartfiles</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3). 使用上面的函数或 GCC 的 -nostartfiles 选项并不是很好的习惯, 因为这<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可能会产生一些意外的结果。相反, 库应该使用<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __attribute__((constructor)) 和 __attribute__((destructor)) 函数属<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 性来输出它的构造函数和析构函数。如下所示:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __attribute__((constructor)) x_init(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __attribute__((destructor))&nbsp; x_fini(void);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构造函数会在dlopen()返回前或库被装载时调用;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 析构函数会在这样几种情况下被调用: dlclose() 返回前, 或 main() 返回<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后, 或装载库过程中 exit() 被调用时。</p>
<p>&nbsp;&nbsp; c. Linux 中的初始化和释放函数不建议使用。</p>
<p>--------------------------------------------------------------------------------<br /></p><img src ="http://www.cppblog.com/kyee/aggbug/146904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyee/" target="_blank">Kyee Ye</a> 2011-05-22 10:55 <a href="http://www.cppblog.com/kyee/articles/146904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>