日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Qt動態庫調用宿主進程中的對象方法純虛函數使用_C 語言

作者:Fake瑞克 ? 更新時間: 2022-10-08 編程語言

引言

可執行程序加載動態庫并調用動態庫導出的函數是比較容易的:

導入庫對應的頭文件

在CPP文件中調用函數

在鏈接程序時加上動態庫作為參數

假設demo.cpp中需要用到動態庫libadd.so中的某個函數,可能是int add(int x, int y),那么我們編譯時就需要鏈接上libadd.so, gcc參數中-L./libs指定了當前目錄下的libs目錄為庫的目錄,-ladd指定了libadd.so動態庫文件,注意這里并未使用全稱,讓編譯器自動適配即可。

// 該方式為靜態導入方式(在程序未運行時完成導入)
gcc demo.cpp -o demo -L./libs -ladd

在運行時加載動態庫并獲取對象指針(QLibrary)

// 導入動態庫
QLibrary m_library;
m_library.setFileName("./libs/libadd.so");
assert(m_library.load());
// 獲取函數指針
typedef int (*FUNC_ADD)(int, int);
FUNC_ADD add = (FUNC_ADD)m_library.resolve("add");
assert(add);
// 愉快的使用add函數
int a = add(125, 125);
qDebug() << a;

本貼重點:在動態庫中調用宿主進程的對象方法

先復習下兩個概念:純虛函數虛函數表

  • 純虛函數在類中定義后是可以不用實現的,子類如繼承含有純虛函數的類必須實現該類所有的純虛函數。純虛函數可作接口使用。
  • C++擁有虛函數表(V-Table),存儲著虛函數地址的表。

假設動態庫需要調用宿主進程的對象方法,在動態庫編譯時時無法獲取到宿主程序該對象的實現的,所以按照正常邏輯是無法編譯通過的。

但是通過上邊有效的復習可以知道純虛函數在調用時可無需實現(在運行時通過查詢虛函數表后獲取實際地址),這樣就可以順利的完成了編譯,當動態庫被加載進宿主進程后就可以正常調用對象的方法了。

還是以add方法為例寫一個Demo

宿主程序:

#ifndef __MATH_H__
#define __MATH_H__
// 接口定義
class IMath
{
public:
    virtual int add(int x, int y) = 0;
};
typedef void (*FUNC_SET_OBJ)(void*);
class Math: public IMath
{
public:
    Test() {
        m_library.setFileName("./libs/libtest.so");
        assert(m_library.load());
        FUNC_SET_OBJ setObj= (FUNC_SET_OBJ)m_library.resolve("setObj");
        assert(setObj);
        // 將Math實例傳遞給動態庫
        setObj(this);
    }
    int add(int x, int y) ovdrride {
        return x + y;
    }
private:
    QLibrary m_library;
}
#endif

然后將接口做成一個獨立的頭文件imath.h,用來給動態庫調用

#ifndef __IMATH_H__
#define __IMATH_H__
class IMath
{
public:
    virtual int add(int x, int y) = 0;
};
#endif

動態庫程序(libtest.cpp):

void setObj(void* obj) {
    IMath* math = static_cast<IMath*>(obj);
    qDebug() << math->add(125, 125);
}

將動態庫程序編譯后放入libs目錄下給宿主程序調用,在宿主程序中實例化Math類,并調用其Test方法,在Test方法中會加載動態庫,并將Math實例的指針傳遞給動態庫,動態庫將Math實例強轉為接口類型并調用其中的純虛函數add()

原文鏈接:https://juejin.cn/post/7130154589654876191

欄目分類
最近更新