人来人往

这些天似乎又到了离职的高峰期,身边又有朋友或依依惜别,或蠢蠢欲动,难道真的万物回春大地复苏?

最近这一两年T公司走了很多人,也来了很多人,作为一个呆了5年的“老”人,不知不觉中发现自己MSN里TM_Old组里的人越来越多,而公司越来越多自己不认识的面孔~~~

每次有人走,总是一阵阵的伤感,一阵阵唏嘘,生命和生活总是得以某种方式继续着,而Little’s Law也早已揭示了一个稳定系统的的法则(系统中物体的平均数量等于物体离开系统的平均速率和每个物体在系统中停留的平均时间的乘积),所以如果假设IT人平均在一个公司呆的时间为5年,则T公司每年流进和流出的人得达到70人(350/5)(呵呵,感兴趣的可以用一下公司的流动率来验证一下公司是否已经稳定;-))

可我们更感动的是每个人的故事,跳槽很多时候其实是一件很慎重的事情,所以每个人都会有自己的充分的理由和抉择,而这其中又包含多少不一样的生活态度和追求。是的,每个人都有自己的理想和梦想,但敢于去追求则总得放下些什么,对于朋友们的选择,我更愿意倾听,听他们人生的理解,也更愿意送出我的祝福,毕竟,有梦的人是幸福的。

记得曾经听过,工作后跳槽的高峰期一般发生在工作2年、5年和10年,而其中2-5年则是高峰期,最近好几个工作2年的朋友的选择似乎更印证了这个说法,如果硬要把这几个高峰期区分一下,或许2年跳槽的是梦想(诱惑),5年跳槽的则是迷茫(屋顶),10年的或许就是无奈了。想想一眨眼自己也为一家公司奉献了5年了,梦想是否还有?

我想是有的,可我看到什么?迷茫~~~看来有必要更多地去思考一下未来~~~

本文网址:http://zoufeiblog.appspot.com/2010/04/25/人来人往.html

Posted in Uncategorized

用SWIG实现Python/C互调用

最近用SWIG把TMUFE封装成Python module,发现SWIG还是非常强悍的,相比于boost-python,SWIG的入门更容易,而且由于可以直接把.so里的interface expose成Python方法,调用起来很方便。

先看个傻瓜教程

SWIG 懒人方法

如上所见,并非总是需要写一个专门的接口文件。如果你有一个头文件,你可以直接在其中包含SWIG接口,如例:

 %module example
 %{
 /* Includes the header in the wrapper code */
 #include "header.h"
 %}
 
 /* Parse the header file to generate wrappers */
 %include "header.h"

只要照上面写个SWIG interface spec,然后:

建立Python模块

转换编码C成Python模块很简单,只需要按如下做即可(请见其他操作系统的SWIG共享库帮助手册):

 
 unix % swig -python example.i
 unix % gcc -c example.c example_wrap.c \
        -I/usr/local/include/python2.1
 unix % ld -shared example.o example_wrap.o -o _example.so 

不过傻瓜教程也就只适用于hello world的sample code了,真正在wrap TMUFE的时候还是遇到一些问题:

1. typedef

发现如果typedef两次,即使是primitive type,也会变成pointer to structure~~~

比如uint32_t在<stdint.h>里被

typedef unsigned int uint32_t;

,如果在interface里又被typedef一次

typedef uint32_t myuint32;

,那么在Python module里如果如果传递int给myuint32参数时,会提示:

 

>>> fn(3,4)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Expected a pointer

解决方法就是在interface里把这个新类型重新typedef一次/或使用命令apply:

typedef unsigned int myuint32;
typedef unsigned long long myuint64;
etc...

OR 

%apply unsigned int { myuint32 }
%apply unsigned long long { myuint64 }

2. 函数指针/回调函数

如果你的C library里有些API需要接受function pointer/callbcack function,在Python里是调用不起来的,Python的方法无法被wrap成函数指针调用。

解决方法是在C里提供callback function的实现,并且让这些函数成为Python API,则可以把这些C函数传递给function pointer。

%module test
%{
#include "a.h"

int add(int x, int y) { return x + y; }
%}

%typedef int (*FUNC) (int, int);
void fn(int, int, FUNC op);

%callback("%s_cb")
int add(int, int);
%nocallback

这个例子实现了函数add,通过%callback把这个函数包装成add(…)和add_cb(…),在Python里可以调用:

from test import *
fn(3, 4, add_cb)	==> 7
add(3,4)		==> 7

看起来SWIG灰常强大,现在还支持C#/Java等和C/C++的互调用,值得再花点时间研究一下~~~

SWIG currently generates wrapper code for eighteen different target languages:

  • Allegro CL
  • C#
  • CFFI
  • CLISP
  • Chicken
  • Guile
  • Java
  • Lua
  • Modula-3
  • Mzscheme
  • OCAML
  • Octave
  • Perl
  • PHP
  • Python
  • R
  • Ruby
  • Tcl
  • UFFI

本文网址:http://zoufeiblog.appspot.com/2010/04/25/UseSwigForPythonC.html

WMI Namepsace Security代码贡献到CodeProject上了

也算是open source了一把,一共在codeproject上发过两次代码:

COM / COM+

General

WMI Namespace Security with C/C++

Last Updated: 19 Apr 2010   Page Views: 4   Rating: 0.0 / 5    Votes: 0   Popularity: 0.0   Bookmark Count: 0

Licence: The Code Project Open License (CPOL)  

Use native API for WMI Namespace Security operation

Internet / Network

HTTP

Asynchronous WinHTTP Library

Last Updated: 11 Dec 2009   Page Views: 3,100   Rating: 3.33/5    Votes: 5   Popularity: 2.33   Bookmark Count: 14

Licence: The Code Project Open License (CPOL)  

Tiny WinHTTP API wrapper library for asynchronous HTTP with callback handler

前一个竟然也有3100个viewer,5个vote,还是不错的;-) 就是写description太累~~~

本文网址:http://zoufeiblog.appspot.com/2010/04/19/WmiSecurity_Src.html

试一下gflags

Google是个好同志,release了很多open source project,很多都是很好用而且有用的~~~

今天试了一下google-gflags,很有用,以后在windows下可以用它了,以前没有getopt只能使用XGetOpt(也很好用,但不够强大,哈哈)

The gflags package contains a library that implements commandline flags processing. As such it's a replacement for getopt(). It has increased flexibility, including built-in support for C++ types like string, and the ability to define flags in the source file in which they're used.

 

 

参考文档:

How To Use Google Commandline Flags (gflags)

本文网址:http://zoufeiblog.appspot.com/2010/04/19/TestGflags.html

Ubuntu 9.10 on T60

最近突发神经,在自己的T60上装了个Ubuntu,至于为什么会装linux,我也想不出什么具体的理由,装b应该占了大多数 既然装了就得折腾折腾,记下来折腾的东西便于以后翻: 1. 事实证明T60上面是没法搞定4G内存的,原因不是由于没有安装PAE内核,也不是CPU不支持PAE,而是主板不支持,害得我提心吊胆的升级了最新的BIOS还是搞不定。WindowXP上面是有工具可以认出来单独划为ramdisk用的,估计是绕过了BIOS,如果谁知道怎么在linux下面绕过BIOS的吱一声 2. 换掉了默认的ibus输入,改为使用scim,装好包后用命令im-switch -z en_US.UTF-8 -s scim设置一下就应该可以了 3. 把apt的source设置为mirrors.163.com上面的源 4. Wine版的QQ: http://tieba.baidu.com/f?kz=682260488 5. taobao跟支付宝的安全登录: http://blog.alipay.com/301.html 6. 电驴用amule,原因是她支持混淆协议 7. Thinkpad的中键(TrackPoint)模拟滑轮, 用xinput设置一下就好了,我是把 xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 8 1 xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 8 2 放到了~/.Xsession, 这样每次重启就自动设置了 8. 放一个可以查资料的网站:www.thinkwiki.org 9. 占位

一点声卡的资料

在网上找了点资料,总结一下: 现在用的pci声卡基本由三部分组成:DSP芯片、I/O控制芯片和Codec芯片。其中DSP扶着一些2D和3D的加速处理,I/O控制芯片负责输入输出控制,Codec负责数字和模拟信号的转换。 后来随着技术的进步,很多声卡将DSP和I/O控制芯片集成在一起了,后来随着CPU主频的上升,有的声卡没了DSP,DSP的工作通过软件交给CPU来做,后来很多I/O控制也集成在了主板的南桥芯片里面,所以就成了主板+CPU+一块Codec就可以出声了,也就是我们常见的板载声卡结构。 结构说完了,说说声卡的工作过程。系统将数字信号通过pci总线或者数字输入接口给声卡,声卡的I/O控制和DSP接受,处理,再传给Codec,Codec转换成模拟后输出。有些声卡还带运算放大芯片,类似我们常说的功放。 可以看出,声卡好首先要做到DSP输出的数字信号要好,其实这个本来不是一个问题,电脑本来就是处理数字信号的,主要是AC97标准规定48KHz采样输出,而常见的cd,mp3,ape都是44.1K采样,所以有个SRC(Sample Rate Convertor)过程,这里就是声卡要解决的关键,有些声卡由硬件解决SRC问题,就没什么好说的了。像Creative由软件进行转换就一直做得不尽如人意。而一般的专业级声卡由于不遵守AC97标准所以一般有两个晶振,分别对应44.1K和48K,所以也没有SRC问题 其次要解决的就是数模转换问题,有些声卡放弃使用集成D/A功能的Codec芯片,而是采用了单独的DAC芯片做D/A转换,目前采用的采样率指标一般为18bit和20bit居多,部分高档的使用了24bit的产品 最后就是声卡的电路设计和做工了,这个和主板显卡之类的东西差不多,什么用料啊,供电啊,防电磁干扰啊之类的,没有这些再好的DSP和DAC也没用

说说GoF模式中的行为模式2

2.Visitor模式 当你把不同的对象比如说String,Float丢到Collection类后,对象都成为Object, 以后遍历的时候如何对不同对象采取不同的操作?if else判断instanceof是最蠢的 办法,visitor模式的想法就是对String,Float等每一个可访问的对象都实现一个 公共接口: interface CommonOperation { public void operation(){ } } class StringElement implements CommonOperation { public void operation() { //自己的操作 } } class FloatElement一样 这样遍历collection的时候就可以通过((CommonOperation)iterator.next()).ope ration()进行操作了,不过这里的缺点是一旦StringElement一定下来,他的操作也 就定了,也就是说客户无法自己更改操作 于是增加一级抽象,引入Visitor接口: interface Visitor { public void visitStringElement(); public void visitFloatElement(); } 然后改写CommandOperation和StringElement: interface CommonOperation { [...]

说说GoF模式中的行为模式6

6. CoR模式: 这个好理解,A,B,C,D都实现处理该请求的接口,来了请求后A先看自己能不能处理 ,不能就 丢给下一个,下一个不能处理继续丢给下一个…… interface Request { public void action(); } class ACanHandleRequest { public void action() { } } interface Hanlder { public void handle(Request request); } class A implement Handler { private Handler nextHandler; public void A(Handler next) { [...]

说说GoF模式中的行为模式5

5.Observer模式 这个java类库已经实现了框架,不过我觉得自己实现也很简单: //对事件感兴趣就实现这个接口,里面的action方法是对该事件的处理过程 interface Listener { public void action(); } //这就是具体的事件产生类,通过notifyListeners通知对事件感兴趣的类 class EventProducer { List list = new ArrayList(); public void addListener(Listener l) { list.add(l); } public void notifyListeners() { for(Iterator i [...]