動態鏈接的總結

第一次寫總結,有錯誤希望各位大神指正!

先引用一位大神的文章

http://blog.csdn.net/ape_neu/article/details/6679246

 

在報上自己的動態庫代碼!

//kewan.h

#ifndef KEWAN_H
#define KEWAN_H

#include "kewan_global.h"

class KEWANSHARED_EXPORT Kewan {
public:
    Kewan();
    ~Kewan() ;

    int ret();    //virtual int ret();
};

#endif // KEWAN_H

 

//kewan_global.h

#ifndef KEWAN_GLOBAL_H
#define KEWAN_GLOBAL_H

#include <QtCore/qglobal.h>


#if defined(KEWAN_LIBRARY)
#  define KEWANSHARED_EXPORT Q_DECL_EXPORT
#else
#  define KEWANSHARED_EXPORT Q_DECL_IMPORT
#endif


#endif // KEWAN_GLOBAL_H

//kewani.h

#ifndef KEWANI_H
#define KEWANI_H
#include "kewan.h"

extern "C"
{
    Q_DECL_EXPORT Kewan* createKewan();
    Q_DECL_EXPORT void deleteKewan(Kewan* k);
}

#endif // KEWANI_H

 

//kewan.cpp

#include "kewan.h"


Kewan::Kewan()
{
}

Kewan::~Kewan()
{

}

int Kewan::ret()
{
    return 123;
}

//kewani.cpp

#include "kewani.h"


Kewan* createKewan()
{
    return new Kewan();
}

void deleteKewan(Kewan* k)
{
    if(k)
    {
        delete k;
    }
}
在新建一個工程使用dll,這邊我簡化了沒有去釋放資源,只是用來演示

#include <QtCore/QCoreApplication>
#include "../kewan/kewan.h"
#include <QLibrary>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QLibrary lib("kewan");

    if(lib.load())
    {
        typedef Kewan* (*CREATE)();
        CREATE cre = (CREATE)lib.resolve("createKewan");
        if(cre)
        {
            Kewan *k = cre();
            qDebug()<<k->ret();
        }
    }

    return a.exec();
}

這時候運行出錯

這是爲什麼,我們使用depend查看一下

發現函數名因爲編譯器變了,這也是爲什麼,我們在使用extern "C"的原因,因爲C裏面函數原來是什麼名字編譯後就是什麼名字。但是C裏面沒有類啊,這時我們怎麼來解決呢?在看了文章開頭的博客後,我發現他用接口來實現,就沒有問題了?爲什麼一定要是接口呢?原來是因爲虛函數的原因,跟其它的沒關係。有虛函數的類會有一個成員變量虛表指針,指向一個虛函數表,虛函數表裏面存放的是虛函數地址。那麼我們再次調用的時候,就會通過虛表指針,找到虛函數表,找到虛函數地址,那麼我們用的就是地址,而不是函數名了,就回避了函數名被編譯器改變的事情。就能成功調用該函數。

那麼上面的代碼只要把kewan.h 裏面的int ret();   前面加一個virtual就可以使用了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章