(原創)乙個簡潔通用的呼叫DLL函式的幫助類

2021-07-10 01:32:11 字數 2582 閱讀 7880

本次介紹一種呼叫dll函式的通用簡潔的方法,消除了原來呼叫方式的重複與繁瑣,使得我們呼叫dll函式的方式更加方便簡潔。用過dll的人會發現c++中呼叫dll中的函式有點繁瑣,呼叫過程是這樣的:在載入dll後還要定義乙個對應的函式指標型別,再呼叫getprocaddress獲取函式位址,再轉成函式指標,最後呼叫該函式。下面是呼叫dll中max和get函式的例子。

void

testdll()

這段**看起來很繁瑣,因為我沒每用乙個函式就需要先定義乙個函式指標,然後再根據名稱獲取函式位址,最後呼叫。如果乙個dll中有上百個函式的話,這種重複而繁瑣的定義會讓人吐的。其實獲取函式位址和呼叫函式的過程是重複邏輯,應該消除,我不想每次都定義乙個函式指標和呼叫getprocaddress,我覺得可以用一種簡潔通用的方式去呼叫dll中的函式。我希望呼叫dll中的函式就像呼叫普通的函式一樣,即傳入乙個函式名稱和函式的引數就可以實現函式的呼叫了。就類似於:

ret calldllfunc(const

string&funname, t arg)

如果以這種方式呼叫的話,我就能避免繁瑣的函式指標定義以及反覆的呼叫getprocaddress了。

如果要按照

ret calldllfunc(const

string& funname, t arg)

這種方式呼叫的話,首先我要把函式指標轉換成一種函式物件或者泛型函式,這裡我們可以用std::function去做這個事情,即通過乙個函式封裝getprocaddress,這樣通過函式名稱我就能獲取乙個泛型函式std::function,我希望這個function是通用的,不論dll中是什麼函式都可以轉換成這個function, 最後呼叫這個通用 

的function就可以了。但是呼叫這個通用的function還有兩個問題需要解決:

不同函式的不同型別返回值怎麼處理,因為函式的返回值可能是某些型別,如何以一種通用的返回值來消除這種不同返回值導致的差異呢?

函式的入引數目可能任意個數,且型別也不盡相同,如何來消除入參個數和型別的差異呢?

我們乙個個解決問題吧,首先看看如何封裝getprocaddress,將函式指標轉換成std::function。通過如下**就可以了。

template std::function

getfunction(const

string&funcname)

其中t是std::function的模板引數,即函式型別的簽名。如果我們要獲取上面例子中,max和get函式,則可以這樣獲取:

auto fmax = getfunction("

max"

);auto fget = getfunction("

get");

這種方式比之之前先定義函式指標再呼叫getprocaddress的方式更簡潔通用。

再看看如何解決函式返回值和入參不統一的問題,關於這個問題,其實在前面的博文中就講到了,不知道的童鞋看這裡: 

(原創)c++11改進我們的程式之簡化我們的程式(一)

是的,還是通過result_of和可變引數模板來搞定。最終的呼叫函式是這樣的:

template typename std::result_of

(args...)>::type excecutefunc(const

string&funcname,args&&... args)

上面的例子中要呼叫max和get函式,這樣就行了:

auto max = excecutefunc("

max", 5, 8

);auto ret = excecutefunc("

get", 5);

怎麼樣,比之之前的呼叫方式是不是簡潔直觀多了,沒有了繁瑣的函式指標的定義,沒有了反覆的呼叫getprocaddress及其轉換和呼叫。

如果要限定呼叫方式就在引數前面加,如

excecutefunc
最後看看完整的**吧。

#include #include 

#include

#include

using

namespace

std;

class

dllparser

~dllparser()

bool load(const

string&dllpath)

return

true

; }

bool

unload()

template

t* getfunction(const

string&funcname)

template

typename std::result_of

(args...)>::type excecutefunc(const

string& funcname, args&&... args)

return f(std::forward(args)...);

}private

: hmodule m_hmod;

std::map

m_map;

};

乙個通用的分頁儲存過程 原創

這是我專案中使用的乙個分頁儲存過程,具有很強的通用性。配合前台asp.net使用50萬條資料基本感不到延遲。資料庫為sqlserver2000。1.分頁儲存過程 原始碼 create procedure pagination str sql varchar 1000 執行的sql 不含order b...

乙個 ORACLE 呼叫 DLL 的例子

注 以下程式在delphi7 oracle9i中測試通過 1 首先用delphi編制乙個dll程式,當然用vb,vc其它語言也可以,本人最近常用delphi,所以以下dll採用delphi程式編制 工程檔案 library project1 uses sysutils,classes,unit1 i...

(原創) 乙個通用的C 訊息匯流排框架

應用開發過程中經常會處理物件間通訊的問題,一般都是物件或介面的依賴和引用去實現物件間的通訊,這在一般情況下是沒問題的,但是如果相互通訊的物件很多,可能會造成物件間的引用關係像蜘蛛網一樣,這樣會導致物件關係很複雜,難以維護的問題,解決這個問題的乙個好方法是通過訊息匯流排去解耦物件間大量相互引用的緊耦合...