之前的版本发完,有空来更新一下之前的gcc和llvm+clang工具链的编译脚本了。其实GCC 7是才release没多久但是llvm 4.0发布其实有一段时间了。

GCC

这回是GCC的脚本有一些改动。因为我现在开发机的环境很多组件并没有装,所以顺带发现了之前的构建脚本的一些问题。

libatbus

经过茫茫长时间的编写+过年在家无聊补充和修正单元测试,再加上这两天的整理,终于把以前的这个关于服务器通信中间件的基本功能和相应的单元测试完成啦。还是可以热烈庆祝一下的。

《关于BUS通信系统的一些思考(一)》 《关于BUS通信系统的一些思考(二)》 《关于BUS通信系统的一些思考(三)》

主要的思路还是在自动选择共享内存或是tcp或是unix socket进行通信。使用节点ID,屏蔽底层通信细节,屏蔽自动重连细节和节点之间自动建立直连的细节。同时基于目前的游戏服务器架构设计方式预留了一些拓展性的设计,以便于后续服务器框架的实现。主要是指全异步,树形结构,自动化的容灾设计和动态扩容缩容,不停服更新,统计等等。

小记最近踩得两个C++坑

记一下最近踩得两个C++独有的暗坑,其中一个和ABI相关。第二个坑其实之前研究过,但是没有实例,这次算是碰到了个典型的实例。

坑一:常量引用失效

在项目中碰到的实例的大致流程是:

  1. 获取某个容易的迭代器,迭代器内包含智能指针(std::shared_ptr)
  2. 把智能指针通过常量引用方式传入函数
  3. 执行过程中智能指针被释放
  4. 于是这时候,我们有了一个空悬的智能指针引用了

用代码表示的话,流程如下:

INI 配置读取库发布

Github地址: https://github.com/owent/libiniloader

OSChina镜像: http://git.oschina.net/owent/libiniloader

项目中经常会碰到需要读取配置的情况,而用ini配置最大的优势就是简单易懂。 但是现在很多的配置读取库都过于庞大了,比如Boost.PropertyTree,功能很强大,但是基本不会用到里面所有的东西。 另外微软的INI读取,功能不是很强不说,还限制在Windows上,更重要的是API设计得实在不优雅。 于是libiniloader就诞生啦。

目录

C++ 的Lambda表达式

C++ 11 标准发布,各大编译器都开始支持里面的各种新特性,其中一项比较有意思的就是lambda表达式。

语法规则

C++ 11 Lambda表达式的四种声明方式

  1. \[ capture \]( params ) mutable(optional) exception attribute -> ret { body }
  2. \[ capture \]( params ) -> ret { body }
  3. \[ capture \]( params ) { body }
  4. \[ capture \]{ body }
  • capture是外部引用的参数
  • params是函数参数
  • 后面可以跟一些函数修饰符
  • ret是返回值类型,如果不指定,会推断一个类型
  • body部分是函数内容 具体用法可以参照C++文档,这里就不复述了

这四个声明式都会返回一个匿名的仿函数实例)。 这里有一个比较重要的一点,就是他是一个仿函数实例,而不是直接一个函数

今年准备安安心心写一个协程库。一方面是觉得协程挺有意思,另一方面也是因为C/C++在这方面没有一个非常权威的解决方案。 按照我自己风格还是喜欢C++,所以协程库定名为 libcopp 。 源码托管在 github: https://github.com/owent/libcopp 镜像托管 http://git.oschina.net/owent/distinctionpp

首先介绍: 什么是协程

协程(coroutine),是一种用户态模拟线程的组件。(具体说明参见:http://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B

C++11标准里有动态模板参数已经是众所周知的事儿了。但是当时还有个主流编译器还不支持。 但是现在,主要的编译器。VC(Windows),GCC(Windows,Linux),Clang(Mac,IOS)都已经支持了。所以就可以准备用于生产环境了。 type_traits没啥好说的。主要是一些静态检测。主要还是要看动态模板参数和他们两的结合使用上。 动态模版参数标准文档见: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf 虽然贴出来了。估计是没人看得。所以就直接说重点。

用过std和boost的function对象和bind函数的童鞋们都知道这玩意用起来腰不酸了,腿不疼了,心情也舒畅了。先上一个简单得示例:

std::string str;
std::function func = std::bind(&std::string::at, &str);
bool is_empty = func();

但是这是怎么做到的呢?看完源码以后,你会发现这里面有着一些很巧妙的设计。

使用代码生成代码是一件十分美妙的事情,于是有了各种代码生成器。但是生成代码,意味着要有对生成规则的分析和处理。 Boost.Spirit 就是这么一个语法分析工具,它实现了对上下文无关文法的LL分析。支持EBNF(扩展巴科斯范式)。 Boost.Spirit 的使用真的是把模板嵌套用到了极致。确实这么做造成了非常强的扩展性,生成的代码也非常高效,但是嵌套的太复杂了,对于初学者而言真心难看懂。 你能想象在学习阶段一个不是太明白的错误导致编译器报出的几十层模板嵌套错误信息的感受吗?而且,这么复杂的模板嵌套还直接导致了编译速度的巨慢无比。 其实在之前,我已经使用过Spirit的Classic版本,即1.X版本,但是过多的复制操作让我觉得当时用得很低效,还好分析的内容并不复杂所以没。体现出来 这回就来研究下功能更强劲的2.X 版本。

这各部分主要是一些很实用和在一些地方帮助编译器自动推断类型的库和函数 首先是引用包装 类名 template< class T > class std::reference_wrapper; 这个类保存了对一个类实例、(成员)函数(指针) 构造时必须传入所引用的对象或引用对象的右值引用 主要方法有 =号操作符, 用于重新绑定引用对象 类型转换操作符, 用于转换为模板目标类的引用类型 get方法, 用于获取引用的对象 ()操作符, 用于执行引用的函数

绑定函数是我认为C++新标准里第二有用的库了 绑定库的使用环境是:

  • GCC-C++ 4.3 及以上
  • Visual Studio 2008 SP1 及以上
  • BOOST 1.25及以上(其中function是1.16及以上)

先来看一段代码

#include 
#include 
#include 
#include 

class button
{
public:

    std::function onClick;
};

class player
{
public:

    void play(void* sender, int param) {
        printf("Play: %d => %d\n", (int)sender, param);
    };
    void stop(void* sender, int param) {
        printf("Play: %d => %d\n", (int)sender, param);
    };
};

button playButton, stopButton;
player thePlayer;

void connect()
{
    playButton.onClick = std::bind(&player::play, &thePlayer, &playButton, std::placeholders::_1);
    stopButton.onClick = std::bind(&player::stop, &thePlayer, &stopButton, std::placeholders::_1);
}

int main () {
    connect();
    playButton.onClick(0);
    return 0;
}
// 以上代码参考boost中bind库示例代码,在G++ 4.6.1中测试通过

木有错,这是C++,并且很方便地实现了委托 这就是传说中的绑定库和增强型的函数对象 接下来一个一个来

这回的两个库没怎么用过,这里的记录就用VC++写了,使用G++和BOOST的时候和智能指针类似。

首先是Tuple

要注意的是这里G++,VC++和BOOST库的函数不太一样,所以使用的时候要注意没有使用到编译器和编译器相关的函数(特别是IDE的弹窗的方法要注意)。

C++ 0x/11 终于通过了,真是个很爽的消息。于是乎我决定对新的东西系统学习一下。

首先当然要从tr1开始,智能指针实际上我已经用过很多次了,但是为了完整起见,还是写出来记录一下。

当然,从简单到复杂,现在接触的部分不是很复杂,不过暂时够用了。