这两天一直在忙着配置中心的开发,现在终于到了python的扩展开发部分,其它都好说,主要是在当c++线程检测到配置更新时回调通知python的问题上,下面来看示例
在python端是这样:

import ConfigApp
def callback(name):
    print 'update_____________', name
config = ConfigApp.Config()
config.register_modify(callback)

上面的register_modify在c++扩展开发中怎么实现呢,且看代码

//回调句柄
static PyObject *update_callback = NULL;
//配置更新通知,参考:http://docs.python.org/2/extending/extending.html 官方demo
static PyObject* Config_method_register_modify(Config *self, PyObject *pArgs, PyObject *kwds){
    PyObject *temp;
    int ret = -1;
    if (PyArg_ParseTuple(pArgs, "O:set_callback", &temp)) {
        if (!PyCallable_Check(temp)) {
            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
            return NULL;
        }
        Py_XINCREF(temp);             /* Add a reference to new callback */
        Py_XDECREF(update_callback);  /* Dispose of previous callback */
        update_callback = temp;       /* Remember new callback */
        ret = AppApi::register_modify(_modify_callback);
    }
    return Py_BuildValue("i", ret);
}

接下来就看我们注册的c++函数_modify_callback的实现过程:

static void _modify_callback(const char *module){
    if (!PyCallable_Check(update_callback)) {
        PyErr_SetString(PyExc_TypeError, "callable have some problem!");
        return ;
    }
    PyObject *arglist = Py_BuildValue("(s)", module);
    PyObject_CallObject(update_callback, arglist);
    Py_DECREF(arglist);
}

看完啊,千万不要把上面代码copy走了!在异步回调的时候出现 :python2.6: line 4: 16251 Segmentation fault
      真要命,这如何是好,主要是我咋搜索呢,百般尝试发现搜索“python extension callback thread”是很靠谱的,最终确认了这样的一篇文章“C++调用PythonAPI线程状态和全局解释器锁 ” ,Py_BEGIN_ALLOW_THREADS这个尝试失败,我就不扯蛋了,直接说官方文档“Initialization, Finalization, and Threads”,按官方现在的代码应该是下面这样的:

//....上面一样,省略
    PyGILState_STATE gstate = PyGILState_Ensure();
    PyObject *arglist = Py_BuildValue("(s)", module);
    PyObject_CallObject(update_callback, arglist);
    Py_DECREF(arglist);
    PyGILState_Release(gstate);
//....上面一样,省略

      啊,回调终于成功了!如果你这个时候走了,那你又悲剧了,因为回调完成后就“Segmentation fault”,然后就继续google,得到结论:http://stackoverflow.com/questions/5140998/why-does-pygilstate-release-segfault-in-this-case,改代码如下:

    //下面这句话很重要
    PyEval_InitThreads();
    //########################
    PyGILState_STATE gstate = PyGILState_Ensure();
    PyObject *arglist = Py_BuildValue("(s)", module);
    PyObject_CallObject(update_callback, arglist);
    Py_DECREF(arglist);
    PyGILState_Release(gstate);

      恭喜恭喜

无标签信息 1 条

      今天一同事突然有个想法找到我来实现,我就先不介绍这个想法了,大意是需要自动生成android应用,中午就随便看了看,确定可行性,因为实在是太忙,只能挪到晚上来研究,终于搞定个大概了,下面做些记录
      首先需要安装ant,这个是必须的,如果已经有了就略过,
wget http://apache.dataguru.cn//ant/binaries/apache-ant-1.9.1-bin.tar.gz
export PATH=$PATH:$HOME/apache-ant/bin

      下面就直接到sdk了,我在http://developer.android.com/sdk/index.html上找了好久,结果藏的也太深了:“DOWNLOAD FOR OTHER PLATFORMS”下载sdk就行了

wget http://dl.google.com/android/android-sdk_r22.0.1-linux.tgz
tar -xzf android-sdk_r22.0.1-linux.tgz
export PATH=$PATH:$HOME/android/android-sdk/tools
#到此环境配置完了,接下来更新sdk,此动作很慢
android update sdk --no-ui #我更新到2.2就停止了
android list targets #找出自己要编译的版本,比如,我的2.2对应的target是1,那么
android create project -n hello -t 1 -p project/ -k com.mjix -a DefaultActivity #参数的解释就直接 --help吧, -t指定target
cd project
ant release #开始编译

      结果出现了一个超级坑爹的事情就是: libz.so.1: cannot open shared object file: No such file or directory,我再三检查,确信自己安装了,可以通过 1、yum -qa|grep zlib或者2、locate libz.so.1来查看,最后终于找到一位知音博客。下面就直接引用了:
因为现在的系统捏是尼玛64位滴,而该死的Android都是基于32开发的,它依赖的是32位的libz
那位同学的解决办法是export CFLAGS=-m32 后再编译zlib安装,我就偷个懒,直接yum install了一个32位的zlib。
      终于,成功的生成了:BUILD SUCCESSFUL。
接下来可以看到bin下面有一个 hello-release-unsigned.apk,未签名的apk,当然不能发布啦,好了,下面我们就来签名吧。

//生成一个自己的签名,其它自己填就好了
keytool -genkey -v -keystore hello.key -alias hello -keyalg RSA -keysize 2048 -validity 10000
//第一种签名方式
vi ant.properties //添加
key.store=hello.key
key.store.password=123456
key.alias=hello
key.alias.password=123456
//执行 ant release就可以看到 hello-release-unsigned.apk
//第二种签名方法:或者使用如下语句生成:
jarsigner -verbose -keystore hello.key -signedjar bin/hello_signed.apk ./bin/hello-release-unsigned.apk hello -keypass 123456
//最终生成的文件是bin/hello_signed.apk
//使用android sdk的zipalign工具优化已签名的apk文件
zipalign -v 4 bin/hello-release-unaligned.apk bin/hello-release-aligned.apk

下面给一些参考链接:
http://my.oschina.net/u/559701/blog/75333
http://developer.android.com/tools/devices/managing-avds-cmdline.html
http://www.android123.com.cn/androidkaifa/173.html
http://developer.android.com/tools/publishing/app-signing.html

无标签信息 2 条