c++动态库链接错误

声明一个父类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 contains a single entry by DongHao published on 09 2, 2009 5:23 PM.

《linux驱动开发详解》 was the previous entry in this blog.

php apc 问题 is the next entry in this blog.

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