第一次寫總結,有錯誤希望各位大神指正!
先引用一位大神的文章
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就可以使用了!