压缩

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 ;
}

Linux使用gcc编译使用zlib库的代码时,使用 -lz 来链接(link) zlib 库。

否则就会出现类似 undefined reference to `deflateInit_’ 的错误

错误原因

我手上一个项目本身采用gcc编译。后来因为代码功能需要移植到g++中时,出现了 “inet_addr” was not declared in this scope 这个错误。

解决方案

// 添加该头文件
#include <arpa/inet.h>

如果出现下面错误:

error: string: No such file or directory
error: vector: No such file or directory
  • 说明在将g++项目用gcc编译

在写代码的过程中,我发现使用VS2012编译出来的程序默认支持的系统版本略高

刚发现在 Win7+VS2012 编译出来的程序默认PE信息(Optional Header):

  • Major SubSystem Version = 6
  • Minor SubSystem Version = 0

导致的结果就是:在WinXP中运行便会提示 不是有效的Win32应用程序

当时还以为是自己搞错编译选项,将程序编译成x64的了。 结果后来使用PE工具才发现的这个问题。

解决方案

右击项目 -> 属性 -> 配置属性 -> 链接器 -> 系统 -> 所需最低版本 填入"5.01"

参考内容

http://msdn.microsoft.com/en-us/library/fcc1zstk(v=vs.110).aspx

SubsystemMinimumDefault
BOOT_APPLICATION1.01.0
CONSOLE5.01 (x86) 5.02 (x64) 6.02 (ARM)6.00 (x86, x64) 6.02 (ARM)
WINDOWS5.01 (x86) 5.02 (x64) 6.02 (ARM)6.00 (x86, x64) 6.02 (ARM)
NATIVE (with DRIVER:WDM)1.00 (x86) 1.10 (x64, ARM)1.00 (x86) 1.10 (x64, ARM)
NATIVE (without /DRIVER:WDM)4.00 (x86) 5.02 (x64) 6.02 (ARM)4.00 (x86) 5.02 (x64) 6.02 (ARM)
POSIX1.019.90
EFI_APPLICATION, EFI_BOOT_SERVICE_DRIVER, EFI_ROM, EFI_RUNTIME_DRIVER1.01.0

Windows下编译安装

生成bjam

bootstrap.bat

编译

bjam --toolset=msvc-11.0 --build-type=complete

安装

bjam --prefix=D:\third_party\boost install

Ubuntu仅安装开发包

sudo apt-get install -y libboost-dev libboost-system-dev

下面代码就可以生成1-100区间的随机数:

#include <vector>
#include <algorithms>

std::vector<int> random_numbers;
for (unsigned int i = 0; i < 100; ++i)
    random_numbers.push_back(i + 1);
std::random_shuffle(random_numbers.begin(), random_numbers.end());

在汇编语言中,我们可以直接使用ROL ROR等指令进行循环左移和循环右移的操作。 但C语言中却没有对应的操作,没办法只能自己实现了。

下面是我最近项目中用到的一个针对WORD类型的循环左移(ROL)实现代码:

uint16_t ROL(int val, int n)
{
    return (val << n) | (val >> (16 - n));
}

针对BYTE类型的循环左移:

uint8_t ROL(int val, int n)
{
    return (val << n) | (val >> (8 - n));
}

针对DWORD类型的循环左移:

uint32_t ROL(int val, int n)
{
    return (val << n) | (val >> (32 - n));
}

android

通过我写的一段Python代码可以让M8用户将联系人导入到Andriod系统中。

操作需要以下步骤:

  1. 先用M8PC工具将M8的联系人导出成XML格式。
  2. 将导出的文件重命名为mycontact.xml,并与m8toAndriod.py放到同一目录下
  3. 运行 python m8toAndriod.py 程序会生成一个名为 mycontact.vcf 的文件
  4. 将 mycontact.vcf 传到Andriod手机中导入

以下为 m8toAndriod.py 的代码:

#!/usr/bin/env python
# coding: utf-8
# 功能:将M8导出的联系人XML转化成Andriod可以导入的vcf文件
# 版本:python 2.6 以上
# 作者:leaker
# 网站:http://www.leelib.com
from xml.etree import ElementTree as ET

# 输出到的mycontact.vcf
out = file("mycontact.vcf", "wb")
root = ET.parse(file("mycontact.xml", "r")).getroot()
print root
for e in root.findall('Person'):
    out.write('BEGIN:VCARDrnVERSION:3.0rn')
    out.write('N:%s;%s;;;rn' % (e.findtext('LastName', '').encode('utf8'), e.findtext('FirstName', '').encode('utf8')))
    out.write('FN:%srn' % (e.findtext('FileAs', '').encode('utf8')))
    # print 'FN:%srn'% (e.findtext('FileAs', '').encode('gb2312'))
    for ee in root.findall('Phone'):
        if ee.findtext('PersonID','') == e.findtext('ID',''):
            primary = ee.get('IsPrimary') == 'true'
            out.write('TEL;TYPE=CELL%s:%srn' % ((';TYPE=PREF' if primary else ''), ee.findtext('Info','')))
    out.write('END:VCARDrn')
out.close()

点击这里下载:m8toAndriod.7z