C++編寫DLL靜態鏈接庫的步調與完成辦法。本站提示廣大學習愛好者:(C++編寫DLL靜態鏈接庫的步調與完成辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是C++編寫DLL靜態鏈接庫的步調與完成辦法正文
本文實例講述了C++編寫DLL靜態鏈接庫的步調與完成辦法。分享給年夜家供年夜家參考,詳細以下:
在寫C++法式時,經常須要將一個class寫成DLL,供客戶端法式挪用。如許的DLL可以導出全部class,也能夠導出這個class的某個辦法。
1、導出全部class
辦法很簡略,只須要在類的頭文件中class和類名之間加上_declspec(dllexport),同時在別的一份供給給客戶端挪用法式應用的類的頭文件中class和類名之間加上_declspec(dllimport)。為了能讓客戶端法式和DLL法式公用該類的一份頭文件,平日在類的頭文件中應用宏和預編譯指令來處置。以下DLLTest.h:
#ifdef DLL_TEST_API #else #define DLL_TEST_API _declspec(dllimport) #endif Class DLL_TEST_API CDLLTest { Public: CDLLTest(); ~CDLLTest(); int Add(int a, int b); };
DLLTest.cpp以下:
#define DLL_TEST_API _declspec(dllexport) #include "DLLTest.h"
如許,在DLL編譯時DLL_TEST_API被界說為_declspec(dllexport),並且客戶端法式編譯時它被界說為_declspec(dllimport)。
2、導出這個類的某個或許某幾個辦法
這時候,須要將_declspec(dllexport)放到成員函數名前,如DLLTest.h:
#ifdef DLL_TEST_API #else #define DLL_TEST_API _declspec(dllimport) #endif Class CDLLTest { Public: CDLLTest(); ~CDLLTest(); int DLL_TEST_API Add(int a, int b); };
然則,假如僅僅是如許的話,當客戶端法式#include這個頭文件後,界說DLLTest這個類的一個對象後(靜態方法鏈接DLL),客戶端法式沒法鏈接經由過程,會提醒結構函數和析構函數沒法解析,此時,須要將結構函數和析構函數前也加上DLL_TEST_API宏便可。
固然這裡還有個成績就是類的函數在導出後,名字會產生變更,我們可以在函數名前再加上extern "C" ,如 extern "C" DLL_TEST_API int Add(int a ,int b);但這只處理了C與C++挪用時名字變革成績,靠得住的辦法照樣增長一個模塊界說文件def,在該文件中界說導出函數的稱號,我們將在前面看到樣例。
DLL編寫完成後,就只剩下客戶端法式若何去挪用該DLL了,靜態方法挪用DLL和靜態方法挪用DLL。
1、靜態方法挪用DLL
這個辦法就簡略了,將DLLTest.h頭文件和DLLTest.lib,DLLTest.dll文件拷貝到客戶端法式確當前目次下,在客戶端法式中#include<DLLTest.h>,然後經由過程#pragma comment(lib,"DLLTest.lib")的方法引入lib庫,或許在客戶端法式的工程屬性外面增長對該lib文件的引入。
然後便可以在客戶端法式中好像應用當地的一個class一樣應用該DLL了,如:
CDLLTest dllTest; dllTest.Add(1,2);
2、靜態方法挪用DLL
靜態挪用這個DLL,就須要對這個class停止修正了。
起首,在DLLTest.cpp文件中增長一個全局函數,該函數可以前往這個class的一個實例,如許,客戶端法式挪用這個全局函數後,獲得該class的實例,便可以挪用該class的實例辦法了。
extern "C" _declspec(dllexport) CDLLTest* GetInstance() { return new CDLLTest; }
注:extern "C" 只是處理了c與c++編譯器之間的兼容成績,假如須要和其他編譯器之間兼容,靠得住的方法照樣增長一個.def文件,文件內容以下:
LIBRARY "DLLTest" EXPORTS GetInstance = GetInstance
如許就指定了DLL的函數導出後的稱號依然不變。
如許,客戶端法式便可以經由過程該函數來獲得class的一個實例了。以下:
先須要界說一個函數指針類型:
typedef CDllTestBase* (*pfGetInst)(); //注:CDllTestBase類前面會引見。 HMOUDLE hMod = LoadLibrary( _T("DLLTest.DLL") ); if(hMod) { pfGetInst pfGetInstance = (pfGetInst)GetProcAddress("GetInstance"); if( p ) { //經由過程基類指針指向派生類對象 CDllTestBase * pInst = pfGetInstance (); if( NULL != pInst ) { pInst->Add( 1,2); } if( NULL != pInst ) { //釋放對象 delete pInst; } } }
固然,這裡照樣須要include這個DLL的頭文件DLLTestBase.h,假如將之前所寫的頭文件DLLTest.h直接拷貝到客戶端法式確當前目次下,並include出去的話,在編譯銜接時,是沒法經由過程的,我們須要對這個頭文件停止修正,起首增長一個.h 文件DLLTestBase.h,在這個文件中我們將須要在客戶端法式中挪用的函數都定名成純虛函數,然後讓CDLLTest類繼續自CDLLTestBase類,DLLTestBase.h以下:
Class CDLLTestBase { Public: Virtual ~CDLLTestBase(){};//虛析構函數,且為內聯函數 Virtual int Add(int a, int b) = 0; }
DLLTest.h修正後以下:
#include "DLLTestBase.h" Class CDLLTest : public CDLLTestBase { Public: CDLLTest(); ~CDLLTest(); int Add(int a, int b); };
注:這裡的DLLTestBase須要供給一個虛析構函數,如許在客戶端法式中便可以經由過程基類指針來釋放派生類對象了。
如許,只須要將DLLTestBase.h拷貝到客戶端法式確當前目次下,然後在客戶端法式中#include"DLLTestBase.h",便可以如下面引見一樣在客戶端法式中挪用DLL外面的辦法了。
願望本文所述對年夜家VC++法式設計有所贊助。