概要

有六种类型的可重用的库:

静态单线程库 (调试/发行版) 静态多线程的库 (调试/发行版) 动态链接库 (DLL)(Debug/Release) 注意每个库都有一个调试版本和发布版本。

Reusable Library            Switch    Library    Macro(s) Defined
--------------------------- --------- ---------- ----------------------
Single Threaded             /ML       LIBC       (none)
Static MultiThread          /MT       LIBCMT     _MT
Dynamic Link (DLL)          /MD       MSVCRT     _MT and _DLL
Debug Single Threaded       /MLd      LIBCD      _DEBUG
Debug Static MultiThread    /MTd      LIBCMTD    _DEBUG and _MT
Debug Dynamic Link (DLL)    /MDd      MSVCRTD    _DEBUG, _MT, and _DLL

下面的代码可以使用可重用库的头文件中以确保一致使用正确的编译器开关:

// MyReusableStaticSingleThreadReleaseLibrary.h
#if defined(_MT) || defined(_DEBUG)
    #error The /ML compiler switch is required.
#endif

// MyReusableStaticMultithreadReleaseLibrary.h
#if !defined(_MT) || defined(_DLL) || defined(_DEBUG)
    #error The /MT compiler switch is required.
#endif

// MyReusableDynamicLinkReleaseLibrary.h
#if !defined(_MT) || !defined(_DLL) || defined(_DEBUG)
    #error The /MD compiler switch is required.
#endif

// MyReusableStaticSingleThreadDebugLibrary.h
#if defined(_MT) || !defined(_DEBUG)
    #error The /MLd compiler switch is required.
#endif

// MyReusableStaticMultithreadDebugLibrary.h
#if !defined(_MT) || defined(_DLL) || !defined(_DEBUG)
    #error The /MTd compiler switch is required.
#endif

// MyReusableDynamicLinkDebugLibrary.h
#if !defined(_MT) || !defined(_DLL) || !defined(_DEBUG)
    #error The /MDd compiler switch is required.
#endif

原文:http://support.microsoft.com/kb/140584/zh-cn

在SSH连接后执行下面命令:

export LANG=en_US
export LC_ALL=en_US

不过上面的修改只是临时的,仅这一次连接有效。等到下次再连接的时候,又得重新调用。所以可以采用下面永久解决这个问题:

echo 'LANG="en_US.UTF-8"  
LANGUAGE="en_US:en"' > /etc/default/locale

通过终端(terminal)命令安装

sudo add-apt-repository ppa:webupd8team/sublime-text-2
sudo apt-get update
sudo apt-get install sublime-text

通过解压官网安装包安装

  1. 将下载的tar.bz2文件解压
tar xf Sublime Text 2.0.1 x64.tar.bz2
  1. 将解压后的文件夹移动到应用程序文件夹
sudo mv Sublime Text 2 /opt/
  1. 设置terminal快速启动命令
sudo ln -s /opt/Sublime Text 2/sublime_text /usr/bin/sublime
  1. 在桌面创建快捷方式
sudo sublime /usr/share/applications/sublime.desktop
  1. 将下面的代码保存进去
[Desktop Entry]
Version=1.0
Name=Sublime Text 2
# Only KDE 4 seems to use GenericName, so we reuse the KDE strings.
# From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413.
GenericName=Text Editor
Exec=sublime
Terminal=false
Icon=/opt/Sublime Text 2/Icon/48x48/sublime_text.webp
Type=Application
Categories=TextEditor;IDE;Development
X-Ayatana-Desktop-Shortcuts=NewWindow

[NewWindow Shortcut Group]
Name=New Window
Exec=sublime -n
TargetEnvironment=Unity

貌似安装sublime3的时候会自动创建快速启动命令,所以如果安装的是3就不用再手动设置了

摘抄自原文:http://my.oschina.net/rc6688/blog/162043#OSC_h2_4

如何安装kernel-devel,可以参考我之前的文章:《Linux下编译驱动发现没有内核源码的解决办法》

下面是我写的一个自动脚本:

cd /usr/src/kernels
cd $(ls -d */ | head -n 1)
ln -s -f $(pwd) /lib/modules/$(uname -r)/build

至于为什么要费劲去 *cd $(ls -d / | head -n 1) 的原因是:很多系统装出来的 kernel-devel 目录名称跟 $(uname -r) 并不一致

至此这个问题修复完成。

在Linux 2.6.33.6中,源文件在:/usr/src/kernels/2.6.33.6/include/linux/skbuff.h

struct sk_buff在2.6.18中的定义:

struct sk_buff {
        /* These two members must be first. */
        struct sk_buff          *next;
        struct sk_buff          *prev;

        struct sock             *sk;
        struct skb_timeval      tstamp;
        struct net_device       *dev;
        struct net_device       *input_dev;

        union {
                struct tcphdr   *th;
                struct udphdr   *uh;
                struct icmphdr  *icmph;
                struct igmphdr  *igmph;
                struct iphdr    *ipiph;
                struct ipv6hdr  *ipv6h;
                unsigned char   *raw;
        } h;

        union {
                struct iphdr    *iph;
                struct ipv6hdr  *ipv6h;
                struct arphdr   *arph;
                unsigned char   *raw;
        } nh;

        union {
                unsigned char   *raw;
        } mac;

        struct  dst_entry       *dst;
        struct  sec_path        *sp;
        /*
         * This is the control buffer. It is free to use for every
         * layer. Please put your private variables there. If you
         * want to keep them across layers you have to do a skb_clone()
         * first. This is owned by whoever has the skb queued ATM.
         */
        char                    cb[48];

        unsigned int            len,
                                data_len,
                                mac_len,
                                csum;
        __u32                   priority;
        __u8                    local_df:1,
                                cloned:1,
                                ip_summed:2,
                                nohdr:1,
                                nfctinfo:3;
        __u8                    pkt_type:3,
                                fclone:2,
#ifndef CONFIG_XEN
                                ipvs_property:1;
#else
                                ipvs_property:1,
                                proto_data_valid:1,
                                proto_csum_blank:1;
#endif
        __be16                  protocol;

        void                    (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_NETFILTER
        struct nf_conntrack     *nfct;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
       struct sk_buff          *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
        struct nf_bridge_info   *nf_bridge;
#endif
        __u32                   nfmark;
#endif /* CONFIG_NETFILTER */
#ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
        __u16                   tc_verd;        /* traffic control verdict */
#endif
#endif
#ifdef CONFIG_NET_DMA
        dma_cookie_t            dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
        __u32                   secmark;
#endif

        /* These elements must be at the end, see alloc_skb() for details.  */
        unsigned int            truesize;
        atomic_t                users;
        unsigned char           *head,
                                *data,
                                *tail,
                                *end;
        /* Extra stuff at the end to avoid breaking abi */
#ifndef __GENKSYMS__
        int                      peeked;
#endif
};

struct sk_buff在2.6.33中的定义:

struct sk_buff {
        /* These two members must be first. */
        struct sk_buff          *next;
        struct sk_buff          *prev;

        ktime_t                 tstamp;

        struct sock             *sk;
        struct net_device       *dev;

        /*
         * This is the control buffer. It is free to use for every
         * layer. Please put your private variables there. If you
         * want to keep them across layers you have to do a skb_clone()
         * first. This is owned by whoever has the skb queued ATM.
         */
        char                    cb[48] __aligned(8);

        unsigned long           _skb_dst;
#ifdef CONFIG_XFRM
        struct  sec_path        *sp;
#endif
        unsigned int            len,
                                data_len;
        __u16                   mac_len,
                                hdr_len;
        union {
                __wsum          csum;
                struct {
                        __u16   csum_start;
                        __u16   csum_offset;
                };
        };
        __u32                   priority;
        kmemcheck_bitfield_begin(flags1);
        __u8                    local_df:1,
                                cloned:1,
                                ip_summed:2,
                                nohdr:1,
                                nfctinfo:3;
        __u8                    pkt_type:3,
                                fclone:2,
                                ipvs_property:1,
                                peeked:1,
                                nf_trace:1;
        __be16                  protocol:16;
        kmemcheck_bitfield_end(flags1);

        void                    (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        struct nf_conntrack     *nfct;
        struct sk_buff          *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
        struct nf_bridge_info   *nf_bridge;
#endif

        int                     skb_iif;
#ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
        __u16                   tc_verd;        /* traffic control verdict */
#endif
#endif

        kmemcheck_bitfield_begin(flags2);
        __u16                   queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
        __u8                    ndisc_nodetype:2;
#endif
        kmemcheck_bitfield_end(flags2);

        /* 0/14 bit hole */

#ifdef CONFIG_NET_DMA
        dma_cookie_t            dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
        __u32                   secmark;
#endif
        union {
                __u32           mark;
                __u32           dropcount;
        };

        __u16                   vlan_tci;

        sk_buff_data_t          transport_header;
        sk_buff_data_t          network_header;
        sk_buff_data_t          mac_header;
        /* These elements must be at the end, see alloc_skb() for details.  */
        sk_buff_data_t          tail;
        sk_buff_data_t          end;
        unsigned char           *head,
                                *data;
        unsigned int            truesize;
        atomic_t                users;
};

有了以上定义的话,我们就可以做类似如下定义来使我们的驱动支持多内核了:

struct sk_buff *new_skb;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
new_skb->mac.raw = (unsigned char *)new_eth_p;
#else
new_skb->mac_header = (unsigned char *)new_eth_p;
#endif

参考:http://www.linuxquestions.org/questions/linux-kernel-70/struct-sk_buff-differs-in-2-6-18-and-2-6-33-kernel-882507/

CentOS 上安装新版本 python

请看: 安装python以及解决版本问题

但在安装新版本后,yum不能正常使用了。原因是yum是基于默认的python版本运行的,例如CentOS6.2基于python2.6。但我们安装版本后建立了链接,覆盖掉了默认python调用,导致yum脚本无法正常调用到自己想要的版本。

解决方案

vim /usr/bin/yum

将第一行 #!/usr/bin/python 修改成 #!/usr/bin/python2.6

安装新版本python

wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2
tar xjf Python-2.7.3.tar.bz2
cd Python-2.7.3
./configure
make
make atlinstall

这时 python2.7.3 版本已经安装成功了。 但调用 python –version 依然会显示并使用旧版本

解决办法就是重新建立一个链接并覆盖掉旧的

ln -s /usr/local/bin/python2.7 /usr/bin/python -f

再调用 python –version 显示结果

[root@centos]# python --version
Python 2.7.3

至此,问题解决 :)

压缩

enData = zlib.compress(data)[2:-4]

对应:

compress2(dstbuf, &dstLen, strSrc, srcLen, 6);

解压

deData = zlib.decompress(enData, -zlib.MAX_WBITS)

对应:

bool gzipInflate( const std::string& compressedBytes, std::string& uncompressedBytes ) {
    if ( compressedBytes.size() == 0 ) {
        uncompressedBytes = compressedBytes ;
        return true ;
    }

    uncompressedBytes.clear() ;

    unsigned full_length = compressedBytes.size() ;
    unsigned half_length = compressedBytes.size() / 2;

    unsigned uncompLength = full_length ;
    char* uncomp = (char*) calloc( sizeof(char), uncompLength );

    z_stream strm;
    strm.next_in = (Bytef *) compressedBytes.c_str();
    strm.avail_in = compressedBytes.size() ;
    strm.total_out = 0;
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;

    bool done = false ;

    //if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK)
    if (inflateInit2(&strm, -MAX_WBITS) != Z_OK)
    {
        free( uncomp );
        return false;
    }

    while (!done) {
        // If our output buffer is too small
        if (strm.total_out >= uncompLength ) {
            // Increase size of output buffer
            char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
            memcpy( uncomp2, uncomp, uncompLength );
            uncompLength += half_length ;
            free( uncomp );
            uncomp = uncomp2 ;
        }

        strm.next_out = (Bytef *) (uncomp + strm.total_out);
        strm.avail_out = uncompLength - strm.total_out;

        // Inflate another chunk.
        int err = inflate (&strm, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END) done = true;
        else if (err != Z_OK)  {
            break;
        }
    }

    if (inflateEnd (&strm) != Z_OK) {
        free( uncomp );
        return false;
    }

    for ( size_t i=0; i<strm.total_out; ++i ) {
        uncompressedBytes += uncomp[ i ];
    }
    free( uncomp );
    return true ;
}