09 2009存档

| | Comments (0) | TrackBacks (0)
妈:(对姨妈说)刚搬来贵州的时候家在车队住,董昊上小学要走好远的路。有一年冬天上学还不小心踩到水塘里了,他也老实,就这么去上了一天的课,回家发现脚都泡白了。
爸:(吃饭中)什么?
妈:你儿子脚泡白了!
爸:哪只脚?

鸡毛掸子

| | Comments (0) | TrackBacks (0)
在遵义家里。

我:(拿起机顶盒上的小鸡毛掸子)咦,这是小时候我挨打的那个鸡毛掸子吗?(看了看)喔,不是,这个小了,是以前那个截短的。
妈:以前那个长,可以掸花瓶上的灰,现在这个短了,只能掸机顶盒上的灰。
我:以后要是再短了,就只能掸杯子里的灰了。以后再短,就只能掸小酒杯里的灰了。
妈:要是再短,就只能掏耳朵里的灰了。
       APC可以给php加速,但我在这里不是介绍APC的。
       项目开发中我们做了一个php module,里面用到了emalloc和efree,用http_load做了压力一切正常,但装了php-apc以后,httpd进程就一个劲的 core dump。后来查到原因是APC接管了emalloc和efree(具体怎么接管的没来得及查,导致emalloc/efree行为和以前不一致,最后崩 溃。
       对于php开发者,APC是透明的;对于php module开发者,APC可就要了命了,先别用emalloc/efree吧。
声明一个父类Parent,两个子类Son和Daughter继承之,分别将两个子类的创建和实现编译成动态链接库son.so, daughter.so,再通过动态库调用的hello方法:
/* parent.h */
class Parent
{
public:
    virtual void hello(void)=0;
    virtual void bye(void);
};



/* son.h */
#include "parent.h"

class Son : public Parent
{
    virtual void hello(void);
};

extern "C" static Parent* createPeople(void);


/* son.cpp */
#include <stdio.h>

#include "son.h"

void Son::hello(void)
{
    printf("son\n");
}

static Parent* createPeople(void)
{
    return new Son;
}



/* daughter.h */
#include "parent.h"

class Daughter : public Parent
{
    virtual void hello(void);
};

extern "C" static Parent* createPeople(void);



/* daughter.cpp */
#include <stdio.h>

#include "daughter.h"

void Daughter::hello(void)
{
    printf("daughter\n");
}

static Parent* createPeople(void)
{
    return new Daughter;
}


/* test.cpp */
#include <stdio.h>
#include <dlfcn.h>
#include "parent.h"

typedef Parent* (Func)(void);

int main(void)
{
    void* handle = dlopen("./daughter.so", RTLD_LAZY);

    if (handle)
    {
        Func* f = (Func*)dlsym(handle, "createPeople");
        if (f)
        {
            Parent* p = f();
            if (p)
            {
                p->hello();
            }
        }
        else
        {
            printf("dlsym:%s\n", dlerror());
        }
    }
    else
    {
        printf("dlopen:%s\n", dlerror());
    }
}

代码如上,现在编译链接:
 
g++ -shared son.cpp -o son.so -fPIC
g++ -shared daughter.cpp -o daughter.so -fPIC
g++ test.cpp -o test -ldl
 
运行test,报错:
 
dlopen:./daughter.so: undefined symbol: _ZTV6Parent
 
找不到符号Parent,那么nm daughter.so看看是不是没有Parent这个符号,结果看到:
.... 
                 U _ZTI6Parent
0000000000100f00 V _ZTI8Daughter
0000000000000ba0 V _ZTS8Daughter
                 U _ZTV6Parent
...
居然有两个Parent符号!其中_ZTV6Parent就是dlopen报找不到错误的那个。初遇这个错误让人头晕,哪里蹦出来两个 Parent?仔细检查最后才发现,Parent有两个虚函数,一个是纯虚函数,一个是普通的虚函数,编译器为这两个虚函数分别生成了两个入口表 _ZTI6Parent和_ZTV6Parent,所以最后链接错误。
改正的方法是干脆把两个虚函数都改为纯虚,当然,这只是很多修改方案中的一个。这里最重要的结论是g++对纯虚函数和虚函数会生成两个链接符号入口,知道这一点,再见到这种链接错误就能处理了。

关于存档

This page is an archive of entries from 09 2009 listed from newest to oldest.

08 2009 is the previous archive.

10 2009 is the next archive.

Find recent content on the main index or look in the 存档 to find all content.