上新浪玩了一把微博,突然依然觉得应该试一下 Twitter,没办法,虽然上面全是老外,但是我依然对如何在中国访问 Twitter 产生了深厚的技术兴趣。
原来可以用 Dabr 来访问 Twitter,当然,最好是能搭一个 Dabr 在自己国外的服务器上:
这样输入你的 Twitter 帐户和密码就可以访问 Twitter 信息了。可是,我发现我对着 Dabr 依然不知道应该玩些什么。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
Linux 下本地写代码的话,有一个 SVN 版本控制还是会好很多的。安装好 SubVersion 后,就可以直接用 svnadmin 命令来 import 一个本地的文件(以下内容摘自《Subversion 权威指南》中文版),比如说:
$ svnadmin create /var/svn/newrepos
$ svn import mytree file:///var/svn/newrepos/some/project \
-m "Initial import"
Adding mytree/foo.c
Adding mytree/bar.c
Adding mytree/subdir
Adding mytree/subdir/quux.h
路径 file:///F|/Zoundry%20Raven/var/svn/newrepos/some/project 就是你想让 svn 保存有关 svn 版本信息的目录,这样,你的目录 mytree 里的内容就提交到了代码仓库里。
然后你可以查一下是否已经提交了一份代码到所指定的路径里:
$ svn list file:///var/svn/newrepos/some/project bar.c foo.c subdir/
注意,在导入之后,原来的目录树并没有转化成工作拷贝,为了开始工作,你还是需要运行 svn checkout 导出一个工作拷贝。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
如果用了 Visual Studio 2005 之类的 IDE 后,对于该类 IDE 提供的前后位置跳转功能,一定会印象很深。
Code::Blocks 也可以装上类似的插件,有一个名叫 Browse Tracker plugins 的插件集合,提供了类似的功能。
Debian/Ubuntu 下可以装上 codeblocks-contrib 这个包,然后就有了 Browse Tracker 的功能。
安装好了以后,可以先通过 Code::Blocks 的菜单 View ==> Browse Tracker ==> Setting,把 Enable BrowseMarks 选上。
默认情况下的使用:
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
项目组如果用 SVN 来管理代码,人一多,谁都可以提交 ( check in) 代码的话,代码很快就会变得混乱不堪,永远也稳定不下来。
这个时候,可以用 SVN 的 patch 功能。我们可以根据自己修改的代码,生成一份和原来代码 diff 后的记录文件,保存下来就成了一个 patch 文件了。代码管理者通过这个 patch 文件,可以很好地观看到修改建议,从而决定是否进行提交。
如果是 TortoiseSVN 的话,要生成 patch 文件很简单,从 TortoiseSVN -> Create patch… 即可生成 patch 文件,保存为以 .patch 或 .diff 结尾的文件即可,如下图所示:

代码提交要使用这个 patch,只需要 TortoiseSVN -> Apply Patch… 即可。
详细的信息可以参考 TortoiseSVN 官方文档。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
MySQL提供了C++语言的操作接口,用这个接口可以针对自己的数据库写一个C++的客户端出来,安装的方法请参看官方文档。
这个文章已经把在Visual Studio 2008里如何编写MySQL Connector C++的应用程序进行了详细的说明,此方法是针对MySQL Connector C++的安装包来介绍的。而另一篇文章则介绍了如何从MySQL Connector C++的源码包编译。
这里介绍一下Visual Studio 2005下面,用安装二进制包的方法来使用MySQL Connector C++的方法:
1) 先安装MySQL
记得要把Developer Components – C Include Files / Lib Files选上。当然,你不安装MySQL而只装这个单独的包也行,不过我还是建议在本地装一个MySQL,否则怎么测试呢?远程测试太麻烦了~~
2) 下载与Visual Studio 2005相对应的MySQL Connector C++版本
3) 在Visual Studio 2005里创建一个Win32 Console工程
File->New Project->Visual C++->Win32->Win32 Console Application
注意:”Application Settings”里的”Additional options: Precompiled header”默认是会被选上的,而我们这里,基本上可以不用这个。
4) 正确地配置工程属性
不管是Debug还是Release,都是用下面的方法设置就可以了,主要是把相关的头文件include到工程,再指定相关的动态链接库所在路径。
(1) 打开”project”->”properties”对话框,选择”configuration properties”
把MySQL Connector/C++的安装目录添加到Additional Include Directory里:
Project->Properties
Configuration Properties -> open tree view
C/C++ -> General -> Additional Include Directory
(2) 让编译器能找到MySQL Connector/C++的libraries,只要把MySQL Connector/C++安装目录里的lib/opt目录添加到搜索路径即可:
Linker -> General -> Additional Library Directories
(3) 编译器在编译的时候,让linker去链接MySQL Connector/C++的mysqlcppconn.lib库
把mysqlcppconn.lib添加到这里:
Linker -> Input -> Additional Dependencies
5) 可以试着编译下面的这段最基本的代码:
/*
examples/standalone_example_docs1.cpp
*/
/* Standard C++ includes */
#include
#include
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
using namespace std;
int main(void)
{
cout << endl;
cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "password");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message");
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
return EXIT_SUCCESS;
}
如果一切顺序,应该就能连上本地的MySQL进行操作了。
最近写了一个神经网络的数字图像识别的程序,刚一开始,被位图的读写搞得晕头转向的。想当年还蛮熟悉的,太久没弄了,知识总是会忘记的!现在写下来,算是记一记笔记,以后再回忆就不会那么痛苦了!
位图文件由三部分组成:文件头 + 位图信息 + 位图像素数据,具体的结构如下图所示:
1、位图文件头。位图文件头主要用于识别位图文件。以下是位图文件头结构的定义:
typedef struct tagBITMAPFILEHEADER { // bmfh
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中的bfType值应该是”BM”(0×4d42),标志该文件是位图文件。bfSize的值是位图文件的大小;bfOffBits是指从BITMAPFILEHEADER开始,直到位图像素数据存储点的内存大小(距离),即用bfOffBits – sizeof(BITMAPFILEHEADER)就能得到BITMAPINFO在位图中实际所占有的空间大小。
2、位图信息中所记录的值用于分配内存,设置调色板信息,读取像素值等。
以下是位图信息结构的定义:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
可见位图信息也是由两部分组成的:位图信息头 + 颜色表。
2.1 位图信息头
位图信息头包含了单个像素所用字节数以及描述颜色的格式,此外还包括位图的宽度、高度、目标设备的位平面数、图像的压缩格式。以下是位图信息头结构的定义:
typedef struct tagBITMAPINFOHEADER{ // bmih
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
2.2 颜色表
颜色表一般是针对16位以下的图像而设置的,对于16位和16位以上的图像,由于其位图像素数据中直接对对应像素的RGB(A)颜色进行描述,因而省却了调色板。而对于16位以下的图像,由于其位图像素数据中记录的只是调色板索引值,因而需要根据这个索引到调色板去取得相应的RGB(A)颜色。颜色表的作用就是创建调色板。
颜色表是由颜色表项组成的,颜色表项结构的定义如下:
typedef struct tagRGBQUAD { // rgbq
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
其中需要注意的问题是,RGBQUAD结构中的颜色顺序是BGR,而不是平常的RGB。
3、位图数据
最后,在位图文件头、位图信息头、位图颜色表之后,便是位图的主体部分:位图数据。根据不同的位图,位图数据所占据的字节数也是不同的:对于8位位图,每个字节代表了一个像素;对于16位位图,每两个字节代表了一个像素;对于24位位图,每三个字节代表了一个像素;对于32位位图,每四个字节代表了一个像素;而对于单色位图来说,每一位代表一个像素。
这里有两点特别需要强调的:
1) 位图数据的字节数组是从图像的最下面一行开始逐行向上存储的,所以在选取源位图的实际范围的时候需要特别注意!
我习惯先用一个函数,把位图数据读成一个和位图结构、方向相似的矩阵,即最先读出的位图数据,是矩阵的最后一行。
2) 存取位图数据的字节数组有个问题需要引起开发人员的注意:字节数组中每个扫描行的字节数必需是4的倍数(即是32位的倍数),如果不足要用0补齐。
举例说,我有一个20 * 20个点的单色位图。在保存位图的时候,第一行有20个点,虽然只需要用20位的数据来保存就可以了;但是,这个时候,不足32位,则需要用12位0来补足。
这样,总共需要 20 * (20 + 12) = 640 位来保存这一行,即需要用640/8 = 80个字节来保存整幅图像。
VC知识库里的这篇文章提供了一个位图操作的类,可以借鉴一下!
据说绿坝里的图像识别用的是OpenCV这个库,作为图像处理专业出身的我,免不了对这个东西产生了一些兴趣。下载OpenCV下来用一用,看看这个东西效果如何。
更多的信息,请访问OpenCV的Wiki站点,例如如何在VC里编译OpenCV的官方文档等等。
下面就是我在Windows XP下,用Visual Studio 2005来使用OpenCV库的设置步骤:
第一步,下载和安装OpenCV库,根据操作系统下载相应的版本。
第二步,把OpenCV库的可执行文件路径加到系统的环境变量PATH里,在我这里是C:\Program Files\OpenCV\bin。
第三步,在Visual Studio 2005里进行必要的全局设置:
1) 在Visual Studio里,选择”Tools -> Options”;
2) 在弹出的对话框里,再选择”Projects -> VC++ Directories”;
3) 在上面的对话框里,从”Show Directories for”下拉框里选择”Library files”;
4) 在Library files列表里, 添加这样一个路径”C:\Program Files\OpenCV\lib”;

5) 从2)的对话框里选择”Include Files”下拉框,然后再添加以下目录:
“C:\Program Files\OpenCV\cv\include”
“C:\Program Files\OpenCV\cxcore\include”
“C:\Program Files\OpenCV\otherlibs\highgui”
“C:\Program Files\OpenCV\cvaux\include”
“C:\Program Files\OpenCV\otherlibs\_graphics\include”

6) 选择下拉框里的”source files”,然后把下面的路径加进去:
“C:\Program Files\OpenCV\cv\src”
“C:\Program Files\OpenCV\cxcore\src”
“C:\Program Files\OpenCV\cvaux\src”
“C:\Program Files\OpenCV\otherlibs\highgui”
“C:\Program Files\OpenCV\otherlibs\_graphics\src”

当然,你应该把上述路径替换成你自己的路径。就这样,Visual Studio 2005里的全局变量就配置好了。
第四步,完成了上述配置,就创建一个OpenCV工程来试一把。
创建一个名叫OpenCVHello的”Win32 Application”或是”Win32 console application”工程,如果想节省编译时间,建议把Precompiled header这个选项给选上。
把以下几个文件include进去,并且要放在stdafx.h文件后面,否则很可能会编译出错。
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
编译一下,应该可以成功。然后我们在主函数_tmain()输入一些OpenCV代码来试试:
IplImage *img = cvLoadImage(“Image.bmp”);
cvNamedWindow(“Image:”,1);
cvShowImage(“Image:”, img);
cvWaitKey();
cvDestroyWindow(“Image:”);
cvReleaseImage(&img);
编译一下,应该会提示一些链接错误的信息。这个时候,从”Project” -> “Properties”打开项目工程的属性,在”Linker” -> “Input” -> “Additional Dependencies”里添加下面这些lib库:
cxcore.lib cv.lib highgui.lib cvaux.lib cvcam.lib

这样应该就可以编译了。整个代码看起来就像这样:

以后有空再深入研究一下OpenCV库的更多用法。
Turbo Vision库是一个tui库,在Windows下有很多种安装方法。你可以用Cygwin, MinGW+MSYS来编译。详细可以看看doc/install里的安装文档。
注意下载相应平台下的版本,Windows下,下载相应的BC++和MinGW版本;而Linux下或是Cygwin下,也有相应的版本。
在Windows下,可以在Cygwin里很简单地进行安装:
$ ./configure
$ make
$ make install
安装完了后,进到目录example里,再把这些例子编译一把:
$ make
如果编译成功了,就可以直接跑一跑这些例子了:
$./demo/demo.exe
整天在自己的电脑上写代码,然后再用ftp上传到服务器(没办法,服务器没有SVN这种高级玩意)。每次上传都不知道哪个文件修改了,导致我得停下来检查一下哪些文件上传了,十分痛苦。
另外,自己在本地写的一些小程序,还是需要经常备份一下,以防止哪天脑残修改出了一大堆的错误回溯不了就麻烦了。
因此,很有必要在本地也搭建一个代码版本管理工具,来帮助我们进行代码、文档的管理工作。
推荐使用SVN作为代码管理工具,搭个svn server,客户端用Tortoise svn,可以整合在资源管理器上面,还可以试试搭一个trac,在线比较差异和查看更改很方便。
下面我们来看看如何在Windows下搭建一个subversion服务器来方便自己的工作。
1) 搭建一个subversion服务器
在Windows下,推荐使用VisualSVN。这个发行版本的安装最简单了,包含了所有我们需要的模块,如subversion,Apache以及一个控制终端。安装很简单,一步一步安装完成即可。
2) 安装一个svbversion的客户端
在Windows下推荐用TortoiseSVN,我不觉得在命令行下一行一行地敲svn命令是一件很开心的事~~
3) 管理你的内容
现在我们只要在VisualSVN里,创建一个代码Repositories,比如说,我现在要写一个Python的工程,创建一个名叫PythonCode的Repositories,设置好相关的属性后,我就用TortoiseSVN来check out这个Repositories。Check Out的地址就是TortoiseSVN在Repositories属性里提供给你的URL地址,类似于:
当然,你可以把计算机名换成localhost,即修改成如下地址:
如果你喜欢用eclipse的话,用Subclipse作为svbversion的客户端也不错:
就这样,你在本地能清楚地看到你这次修改了哪些文件,只要把这些文件上传到服务器即可。这下就不用每次抓狂地回忆究竟修改了哪个文件!
最近,一直在苦苦寻找一个最适合自己的bug追踪系统。我自己平时写的一些小工具,有一些bug需要追踪管理一下,用记事本显得格式太随意了,不好管理。
试了很多有名的工具,如Bugzilla,Mantis,感觉都太厚重了,团队用倒是蛮合适的。
后来想着用XML定义一个日志数据库,一个Bug开一个文件,这样可以详细记录Bug的内容及解决过程、方法等。再写一个前端,用来管理组织这些XML文件。但我个人的bug量不多,更多的时候,是随手写一点想法,这种XML严谨的组织方式,并没有让我觉得更轻松。
尝试着用Emacs Muse记录了一段时间,有一个缺点,就是我写下来的解决方法里,有很多是代码,如果我不加<verse></verse>标签,Muse会尽量地帮我重新转义一下。总的来说,Muse还是偏排版多一点,不适合于记录随想随写的东西。
最后,我发现用Perl的pod来做自己的bug追踪系统挺好的。Pod虽然是个文档系统,但是只要灵活地运用标签也是能做简单的bug追踪系统。Pod的优点是,当你不需要用命令的时候,直接输入你的内容即可,总体来说,比较简洁。
我的pod格式定义如下:
=pod
=head1 project 1
=head2 Bug #000001
=head3 Bug #000001的简单描述或标题
Bug #000001的详细描述,所有的有关内容。。
=head3 Bug Status::Fixed
=head3 Bug解决方法记录
=over indentlevel
=item 解决步骤一
解决步骤一的内容。
=item 解决步骤二
解决步骤二的内容。
=item Bug Fix summary
Solution of Bug #000001, the summary of this bug is:
Try to readcord the document in time and in style.
这里就写一写把Bug搞定后的总结。
=back
=head2 Bug #000002
=head3 Bug #000002的简单描述或标题
Bug #000002的详细描述,所有的有关内容。。
=head3 Bug Status::Active
=head3 Bug解决方法记录
=over indentlevel
=item 解决步骤一
解决步骤一的内容。
=item 解决步骤二
解决步骤二的内容。
=item Bug Fix summary
Solution of Bug #000002, the summary of this bug is:
Try to readcord the document in time and in style.
这里就写一写把Bug搞定后的总结。
=back
=head2 Bug #000003
=head3 Bug #000003的简单描述或标题
Bug #000003的详细描述,所有的有关内容。。
=head3 Bug Status::Suspended
=head3 Bug解决方法记录
=over indentlevel
=item 解决步骤一
解决步骤一的内容。
=item 解决步骤二
解决步骤二的内容。
=item Bug Fix summary
Solution of Bug #000003, the summary of this bug is:
Try to readcord the document in time and in style.
这里就写一写把Bug搞定后的总结。
=back
=cut
把上面的例子代码存成一个文档,比如说,我喜欢存为WaterBug.txt,后缀用.txt是为了方便用其它编辑器查看。
用pod2html的命令生成文档给其他人观看:
pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug
当然,你可以为这个文档写一个你自己的Style Sheet,生成一个打着你的logo的个性化文档:
pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug –css stylesheet.css
在定义我的pod格式时,我分别用Active,Suspended,Fixed,On-hold四种状态来标明Bug的状态,即”正在进行”、”还未开始”、”已经搞定”、”暂时放着”等四种状态,这些状态关键字都是以::开头进行标识。
以这些简单的标记来记录文档,我可以随手写在任何文本文件里,包括Google Docs这些在线文档,即使将来要转成其它格式的文档,也可以轻松地用perl来实现转换。
要查找特定状态的bug,只要搜索一下::Fixed或是::Suspended或是::Active或是::On-hold即可。