我的 2013

2013 年的关键词:“忙”。

  1. 经历完 12 年底那段比较忙的时间,13 年上半年相对放松一些,甚至有过整整一周都没加班的记录(嗯,加入公司近两年,这是唯一一次),到下半年工作内容有些调整,团队里也有一些人员上的变动,除了之前校正(Calibration)方面的开发、集成工作还在继续,在软件的系统需求、版本发布方面也投入了不少的时间精力,加上自留地采集(Acquisition)方面时不时也有点事情,总体来说,事情比较杂,时间相当不够用,只能说努力将事情都尽量做好吧,至少要对得起自己,嗯。年后开发方面的主要精力要投入到软件部门的另一个团队,不太熟悉的领域,又有很多可以学习和需要学习的东西,加油!
  2. 生活方面,我和果妈工作上都进入比较忙的状态,基本都是一早出门,晚上九十点回家,还是非常感谢爸妈,自己能做的也只能说在家的时候多陪爸妈聊聊天了。。。国庆的时候回了一趟老家,说话上一次回老家还是 08 年送爸妈回去,这回是给老爸庆祝 70 大寿,也是果果第一次去果爸的老家,小家伙很开心,每天都粘着昕颖姐姐:)另外,爸妈今年夏天的时候又一次登上了老家的武功山,长辈的精神一如既往地值得俺们后辈学习!
  3. 果果继续健康成长,表达能力有了长足的进步,也能认识不少的汉字,最近在爷爷的教导下,已经开始每天晚上练习写字了(或者说画字,嘿嘿)。年底前果果在幼儿园碰到一些小的挫折,甚至都有点害怕去幼儿园了,过了两三个星期才基本恢复过来。果果在成长过程中一定还会碰到更多的不顺利,但相信果果可以在这些不顺利中学到更多,你可以的!
  4. 读了一些,不管是技术或是非技术相关,闲书居多,需要静下心来花时间阅读的很少,有好几个坑还是前些年留下来的。“专注,是这个时代的稀有名词”,希望自己新年里在学习方面能适当地更专注一些,也许减少同时挖坑数(WIP!)是个可以尝试的起点。
  5. 今年也开始比较多地消费电子书,刚统计了一下,一年下来大概有110+支出在电子书上,虽说总金额上大概只是纸质书投入的 1/5,但其实数量上已经超过不少了(只淘便宜书,嘿嘿)。体验方面总体还可以,但也碰到一些问题,比如《图灵的秘密》,制作得是不是很精美我其实也不是太关心,但出现一些关键内容上的错误(和纸质书比较过,应该还是校对上的问题),感觉真心不好。
  6. 说到专注,现在小孩的家庭教育也是个问题,传统玩具以外,还有平板、手机、游戏机等众多数码产品来吸引、分散小孩的注意力,加上自己下班回到家一般也会比较疲惫,也就有意无意地放松了一些在小孩成长教育方面的引导。仍然坚信父母言传身教对小孩的影响,希望新年可以做得更好些,不求有功,但求无过。
  7. 偶尔还会跑跑步,晚上如果加班后再回家的话也换了条需要步行将近 20 分钟的路线,也算是锻炼身体吧。话说 12 年刚加入公司时,因为生活习惯变化比较大,还瘦了好几斤(高兴),结果没多久就恢复原样了(好吧),最近半年更是不像话地开始顺势上涨(没天理),是不是该适当地控制饮食啦?(喂,年后公司食堂要免费了诶)
  8. 从还在大学读书的时候开始,就陆陆续续收集了不少感兴趣的 PC 游戏大作,说是收集,其实更多应该是说“暂时没时间玩,以后有空了再来吧”的意思,但是今年突然觉得,那些个还没动过的游戏,也许还真是再也不会有时间有精力去玩了。。。今年夏天 Mass Effect 3 草草通关,一年一部的节奏,算是给 15 年左右的 PC 游戏生涯画上了一个还算凑合的句号吧。
  9. 回顾去年的展望,完全实现的貌似只有 Nexus7。。。还不错,身材+屏幕+性能+价格得到了较好的平衡(不要提 Google 服务在天朝的可用性就好),打发了不少上下班路上的时间,一半看书,一半看片,于是手机就被冷落了,屏幕大小是硬伤。14 年要不要搞个 Xbox One 呢?

未了,引用《2013 年的十个好想法》里的一段话:“不一定要那么大众,那么出彩,那种形式,才算作品。不同的人,不同的阶段对作品都有着不同的定义。作品也有拿的出手的和拿不出手的之分。但如果你对「作品」完全没有了创作欲望或决心又碰巧是个好学的人,那么我说的求知瘾者可能就是你。

 

发表在 生活, 读书, 游戏 | Tagged , , , , | 1条评论

SignTool Error: File not found:

最近更新了手头维护的一个驱动程序,想要重新打上数字签名,结果老是报“SignTool Error: File not found:”这个错误,搞郁闷了,后来发现还是自己对公钥私钥的概念没搞清楚。

去年是参照M$官网上的说明,用 makecert 生成一个测试证书,然后再通过 signtool 来使用这个证书给驱动程序签名,同时将 .cer 文件随驱动程序一起分发,以方便 win7 x64 能自动加载这个驱动程序。

后来工作机的硬盘坏了后,找 IT 重新安装了系统,以为直接将原来生成的 .cer 文件导入就可以了,于是就发生了前面说的错误。

就俺现在的理解,.cer 相当于公钥,而 makecert 在生成 .cer 时,同时还生成了对应的私钥文件并且导入到系统中,所以后来直接将 .cer 导入其实是没用的,这个只能用来验证签名,而不能用来生成签名。

为了防止再发生这样的事情,应该在生成新证书后,连带私钥一起导出成 .pfx 文件并备份好,这样以后万一机器再出问题就可以重新导入了。

发表在 软件开发 | Tagged , | 发表评论

我的 2012

多亏玛雅人的预言不靠谱,才有机会总结这过去的一年~

  1. 最大的变化是离开了过去8年所在的公司,从毕业起带着一些懵懂的加入到8年后有一丝遗憾的离开,感谢原公司带给我的所有的技术和非技术的收获,更感谢原公司可爱的同事们留给我的很多美好回忆~
  2. 新加入的公司,工作强度相较前公司大为增加,原公司一般是将近9点出门6点前就回到家,而现在基本是早7点多出门,晚10点后才到家,从通信跨到医疗,有太多的行业知识还需要补充,虽然干的活基本还就是写代码,但也接触了不少之前没机会实践的东西,比如Scrum、单元测试、自动化构建等等,当然,也结识了不少有趣的新同事,总体来说,挺好。
  3. 果果的2012是入学元年,从去年初话都不会说几句,到现在家里人总是开玩笑地说果妞说话太啰嗦,这中间的变化着实不少。前年果妞在外婆家舒舒服服地呆了一年,回来后也许是环境适应的问题,整个上半年生病的次数还挺多,美林泰诺什么的吃了不少,所幸熬到下半年就几乎没生过病啦:)
  4. 感谢爸妈,都是将近70的人了,还不远千里在这帮我带小孩做家务,所幸爸妈身体都还算不错。虽然在这边没什么熟人,希望爸妈也能开开心心,老有所乐,少玩祖玛多运动哈~
  5. 感谢果妈,果妈今年的工作强度也相较往年有所增大,很多时候一周也休息不了一天,但在家的时候,基本晚上都不需要我来照看果妞了,让果爸能尽可能地休息好,功劳不小,小红花送上~不过有个新问题是果妞现在太粘果妈,超级太醋坛子。

然后是些比较琐碎的事情:

  1. 困扰多年的卫生间渗水问题终于得到彻底解决,Oh yeah~
  2. 俺的智能手机元年,打发了不少上下班路上的时间~
  3. 近几年来第一回到冬天的时候血压还基本正常,原因不详,难道血压高也是闲出来的?
  4. 上半年比较空的时候经常还会在小区里跑跑步,可惜到新公司后就很难再有时间了,只能很偶尔在家里跳跳绳:)

顺便展望一下2013?

  1. 习惯上,希望做事情的时候更专注些!
  2. 技术上,希望能有更多的时间、更多的决心、更系统地来多学习一些新东西,至少,能把手头正在读的一些书完成吧。
  3. 工作上,希望公司能逐渐步入正轨,大家的加班可以少一些,工作可以做得细致一些。换句话说,希望能早日脱离华丽无比的SDD开发方式。。。
  4. 语言上,希望自己的英文听、说能力还能再OK一些~
  5. 生活上,希望家人能一起出去旅游一次,至少,不带上我也行:)
  6. 呃,貌似还需要一台7寸左右的平板,用来看看书,要不要等下一代的Nexus7呢?
发表在 生活 | 发表评论

2012 in review

The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.

Here’s an excerpt:

600 people reached the top of Mt. Everest in 2012. This blog got about 2,000 views in 2012. If every person who reached the top of Mt. Everest viewed this blog, it would have taken 3 years to get that many views.

Click here to see the complete report.

发表在 Uncategorized | 发表评论

2011 in review

The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.

Here’s an excerpt:

A New York City subway train holds 1,200 people. This blog was viewed about 5,300 times in 2011. If it were a NYC subway train, it would take about 4 trips to carry that many people.

Click here to see the complete report.

发表在 Uncategorized | 发表评论

cppdb

简介

cppdb 是一个跨平台的 C++ 数据库操作类库,可以从 sourceforge 下载源码包或者直接从 SVN 库中检出。

编译 (VS2008)

首先使用 CMake 生成项目文件,下载后解压,运行 /bin/cmakegui.exe,需要设定 cppdb 的代码目录和项目文件的输出目录(比如在 cppdb 下面新建一个 build 目录,清楚一些)。

然后是配置,大致步骤:

  1. 点击 Configure 按钮,选择 VS2008
  2. 选中 DISABLE 组下面的的:DISABLE_ODBC、DISABLE_PQ、DISABLE_SQLITE
  3. 选中 MYSQL 组下面的 MYSQL_BACKEND_INTERNAL(这样最终就生成一个 cppdb.dll,不然还要附带一个 cppdb_mysql.dll),并分别设定 MYSQL_LIB 和 MYSQL_PATH 为 C:/Program Files (x86)/MySQL/MySQL Server 5.0/lib/opt/libmysql.lib 和 C:\Program Files (x86)\MySQL\MySQL Server 5.0\include(我机器上的操作系统是 64 位 Win7)。
  4. 再点击 Configure,应该没有红色的配置项了
  5. 点击 Generate,项目文件将在指定的目录下(cppdb/build)生成

然后就可以用 VS2008 来打开 cppdb/build/cppdb.sln 了,直接编译会碰到两个问题:

1. error C2146: syntax error : missing ‘;’ before identifier ‘fd’

这个需要在 mysql_backend.cpp 的开头加上一句:

#include <winsock2.h>

2. illegal token on right side of ‘::’

这个错误的相关讨论可以参照这篇文章,文中给出的方法需要将代码中的

if(v > std::numeric_limits<T>::max() || v < std::numeric_limits<T>::min())

修改成:

if(v > (std::numeric_limits<T>::max)() || v < (std::numeric_limits<T>::min)())

但评论中还有更直接的方法,在项目属性里面定义一个 NOMINMAX 就好了。

使用中碰到的问题

1. cppdb::statement::affected()

我代码中有时需要更新一条可能不存在的记录,如果不存在,就直接插入一条新记录,而存在与否,就是调用这个 affected() 来判断,然后碰到的问题是明明记录已经存在,更新操作也执行成功(虽然字段内容没变),但 affected 返回的值仍是 0。

跟踪了下 cppdb 的代码,最终调用的是 mysql_stmt_affected_rows(),然后查到 MySQL 的官方文档里是这样解释的:

For UPDATE statements, the affected-rows value by default is the number of rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is the number of rows “found”; that is, matched by the WHERE clause.

找到原因就好办了,直接修改 mysql_backend.cpp,将

if(!mysql_real_connect(conn_,phost,puser,ppassword,pdatabase,port,punix_socket,0))

中最后一个参数 0 修改成 CLIENT_FOUND_ROWS 就好了。

2. cppdb::statement::reset()

示意代码:

cppdb::statement st = _conn << ….
cppdb::result r = st.query();
st.reset();
r.fetch(“”, v);    // bang!!!

必须在 r 使用完成之后,才能调用 st.reset()。

3. cppdb::statement::bind()

传入的字段值类型是 std::string 时,bind 操作内部直接使用了 std::string::c_str() 生成的临时字符串!所以如果 std::string 自身也是临时变量的话,就要当心了。。。

std::string getValue(…) { …}

cppdb::statement st = _conn << …
st.bind(1, getValue(…));

st.exec();    // bang!!!

只能这样写:


std::string s = getValue(…);
st.bind(1, s);

st.exe();   // ok~

发表在 软件开发 | Tagged | 发表评论

mkv 转 mp4

说明

1. 两种都是容器格式,mkv 常见于 0Day 各种高清视频资源的封装,之所以要转是因为 iOS 原生不支持 mkv(话说也没什么操作系统会原生支持吧),这样除了可以直接用 iOS 直接播放(当然,容器内的音视频编码格式也要是 iOS 能支持的),还能在用第三方的播放器应用比如 AVPlayerHD 播放的时候,利用到设备的硬件解码能力。
2. 高清 mkv 中的视频流一般是用 h.264 编码的(开源的应该叫 x264 吧),后者在 iOS 上原生支持,所以最好能在转移过程中不对其重新编码,也就是说主要是封装格式的转换(remux),不然耗费的时间就不值得了。而音频流很可能是 ac3,需要转换成 aac 才能放到 mp4 里头,还好,这个操作需要的时间相对比较短。

步骤

1. 分离 mkv 内的音视频流(demux),两种方法都可以:
1) mkvextract,命令格式类似:mkvextract.exe tracks src.mkv 1:v.264 2:a.ac3
2) tsMuxeR,有 GUI 就不需要解释了。

2. ac3 转 aac,也尝试了两种方法:
1) ffmpeg,命令行有点麻烦,而且一直没试验成功,各种看不太懂的错误信息。。。
2) eac3to + NeroAACCodec
将后者解压后得到的 neroAacEnc.exe 复制到 eac3to 的目录下,到时候要用这个来编码。
命令格式类似:eac3to.exe a.ac3 a.mp4
我在笔记本上转移了一个 50M 的 ac3 文件,大约耗时 2 分钟。

3. 合成 mp4(mux),继续尝试:
1) ffmpeg,继续失败。。。
2) mp4box,命令格式类似:MP4Box.exe -add v.264 -add a.mp4 -new final.mp4
3) My MP4Box GUI,又有 GUI 了。

后记

1. 大概是因为 iPad2 的双核处理器比较强悍,AVPlayerHD 直接就可以流畅播放较高码率的 720p mkv 视频,那看来前面都白搞了。。。拿了一集 TBBT 做样本,转换前后的差别仅在两倍速播放的时候才能看出来:)
2. 之前一直用 Handbrake 将相机拍摄的视频从 .mov 格式转换成 1/3-1/4 大小的 .mkv 格式,但在 Win7/Vista 上需要借助第三方软件才能实现 .mkv 格式文件的预览,如果转成 .mp4 格式应该可以直接预览,反正这些 .mkv 里头都已经是标准的 h.264 和 aac,转换起来也快,只是需要写一个小工具来批量处理,不然上千个文件。。。:)
3. 从网上看到,Mac 平台可以用 QuickTime Pro 配合 Perian 来完成这个转换,不过更方便省钱应该是用 MKVTools:)

后记 @111205

1.  MP4Box 可以在 -add 参数中指定 fps,例如:mp4box.exe -add v.264:fps=30 -add a.aac -new final.mp4,像我的 IXUS 870 IS 录制的 .mov 文件的 fps 是 30,然后用 Handbrake 转成 .mkv 后的 fps 还是 30,如果不指定这个参数的话,最终合成的 .mp4 文件就会音画不同步了。
2. 才发现 Handbrake 的输出就是标准的 mp4 格式,只是在文件扩展名上使用了对 iPod/iTunes 友好的 .m4v,而且这个可以在软件菜单的 Options 里进行设置,那看来以后都没必要再转 mkv 了,一步到位才好。

发表在 软件应用 | Tagged , , , | 1条评论