QT調VC的DLL實驗總結

2021-07-12 02:34:28 字數 2452 閱讀 8016

本文主要介紹」如何在qt程式中呼叫vc的dll庫「,包括:隱式載入和顯式載入、編譯選項、匯出函式、呼叫約定和錯誤分析。

一、開發環境

1,qt5.4.1 + mingw compiler,生成caller程式。

2,vs2015,生成win32 dll庫。

二、隱式載入

1,新建vc的dll

使用vs2015新建win32 dll專案 —— testdll。新增如下**:

// testdll.cpp : 定義 dll 應用程式的匯出函式。

//#include "stdafx.h"

extern "c" int __declspec(dllexport) __stdcall foo(int a, int b)

1)它使用c方式匯出函式。

2)它使用__stdcall呼叫約定,vs預設為__cdecl,故此處要顯示註明。

2,新建qt的caller.exe

使用qcreator新建qt控制台應用程式。並進行如下修改:

1)在.pro檔案新增匯出庫的.lib檔案所在位置和名字。如下:

libs += -l $$_pro_file_pwd_/lib -l testdll
它實際上就是新增了一條編譯命令 —— libs,其中附帶選項」-l「(大寫),其值為.lib檔案所在目錄。我在此使用的是」$$_pro_file_pwd「巨集,其中前兩個符號是路徑抽取符,後面的巨集是指.pro所在路徑,同時,我需要在該路徑下新建乙個資料夾」lib「,並把」testdll.lib「檔案放在裡面。此外,需要注意的是,qt中的路徑字串遵循linux標準,使用的是斜槓(slash),windows實際使用反斜槓(backslash)。

該編譯命令的第二個選項是」-l"(小寫),它指定.lib檔名,不帶字尾,這樣可以相容windows下的.dll和linux下的.so檔案。

2)在「main.cpp」中宣告被調函式。

extern "c" int __stdcall add(int, int);
在實際專案中,可以直接包含匯出庫的.h檔案。但是,需要指定.h檔案的路徑,它需要在.pro中新增「includepath」編譯命令。

3)呼叫測試

在main函式中直接呼叫

int result = add(2, 3)

4)將testdll.lib檔案拷貝到上面指定目錄下。

5)將testdll.dll檔案拷貝到執行目錄下,即和caller.exe在同乙個目錄下。

如此,程式即可正常編譯和執行,並可debug檢視正確呼叫後的結果 —— 「result 的值為5」。

3,錯誤分析

1)如果沒有將.lib檔案放到指定位置,編譯時將報鏈結錯誤,找不到指定的lib檔案。

2)如果函式匯出方式(extern 」c「)不一致,或者呼叫約定不一致(__stdcall或__cdecl),編譯時將報鏈結錯誤,找不到指定的匯出函式。

3)如果.dll檔案沒有放到」可執行檔案目錄「,不會報編譯錯誤,在執行時將彈錯誤框「執行失敗」,並顯示「during startup programexited with code 0xc0000135」。

綜上,隱式載入方式在編譯階段會去解析.lib檔案,並將匯出函式符號鏈結到程式中。而真正的庫函式,是在程式啟動階段進行載入。

三、顯式載入

qt顯式載入主要是利用qlibrary類。

qlibrary lib("testdll");

lib.load();

int result = 0;

if (lib.isloaded())

1)它實際上是在執行時通過resolve函式去.dll檔案中找匯出函式符「add",找到後返回該函式的位址,實際上是乙個偏移量。

2)可以用void*去接收resolve的返回值,後面呼叫的時候再轉換為對應的函式指標。

3)該方法在我的實驗來看,只適合」__cdecl「呼叫約定匯出的函式,如果dll中的函式使用」__stdcall「方式匯出,resolve函式的返回值為」0"。即使將函式指標宣告為如下形式:

typydef int(__stdcall*funcptr)(int, int);
因為,實際上是resolve函式沒有解析出相關的匯出函式。

相關參考:

qt5中動態鏈結庫的建立和使用

qt呼叫vc的dll

上文提到的「隱式呼叫"的方法:

libs += -l *** -i ***

該方法只適合mingw編譯器,vc編譯器直接用」#pragma comment(lib, "***")",否則報錯:

lnk1146:沒有選項「:libspath"指定的引數

命令列編譯參考:gcchowto 和 從c++到qt

QT隱式呼叫VC開發的DLL

首先用vs開發乙個簡單的dll 標頭檔案testdll.h include extern c int winapi add int x,int y 源 檔案 include testdll.h int winapi add int x,int y 接下來建立乙個qt工程 在專案檔案中新增如下配置 i...

VC呼叫QT的dll 問題解決

前提 qt寫的介面,轉換成vc可呼叫的dll。問題1 編譯通過,但出現dll裝載控制代碼為null,getlasterror 返回126,如下 setcurrentdirectory e 目錄為e abc.hmodule handle loadlibrary abc.dll 為qt生成的庫 int ...

可供VC呼叫的QT編寫的介面DLL方法

一般直接編寫的qt動態庫是無法被windows下的vc6.0等呼叫的。如下步驟 第二步 在qt的proc檔案中新增以下的一行 include,路徑自行修改 第三步 在需要到處的動態庫dll的cpp檔案中包含如下有關qtwinmigrate的標頭檔案 第四步 基於前面的工作,如果你到處動態庫,你需要呼...