2012-06-06 26 views
0

正如我們所知,我們可以使用GetProcAddress的獲取某個DLL處理函數指針,如在一個DLL定義的方法foo:如何使用GetProcAddress的動態

int foo(long) 

,我們可以得到函數指針像這樣foo的功能:

typedef int(* FOO_FUNC)(long) 
FOO_FUNC pFooFunc = (FOO_FUNC) GetProcAddress(dllHandle, "foo") 

但是我們想,如果我們可以做到動態進一步,讓我們說,我知道我有輸入參數,並將其類型的列表,這是當前的方法正確,我想在dll上調用這個方法,然後得到一個輸出參數列表(其類型爲)

//VARIANT would be able to hold different type of data with different type 
std::vector<VARIANT> inputArguments; 
std::string methodName = "foo" 
void * pFunc = GetProcAddress(dllHandle, methodName.c_str()) 
std::vector<VARIANT> outputArguments; 
callMethodDynamically(pFunc, inputArgument, &outputArguments) 

是否有可能在C/C++中實現上述callMethodDynamically?我能想到的唯一方法是我們必須將參數推入堆棧,然後調用pFunc。我想那會是彙編語言。這裏還有其他的方法嗎?我們也必須在這裏處理不同的調用約定(stdcall,cdecl)。

+1

對於一些調用約定,您需要一個彙編thunk。例如,在x64上只有一個調用約定,它是一個快速調用約定,因此您必須能夠註銷參數。您可以用純C++僞造大多數x86 stdcall函數,但會有一些醜陋的強制轉換。 –

+1

作爲另一種選擇,你有沒有考慮過使用COM(或XPCOM)?因爲你在很大程度上試圖複製它的設計目的。除非你試圖在任何不以這種方式寫入的任意DLL上執行此操作,哪種情況...哪裏可以獲得有關inputArguments和outputArguments中實際類型的信息? – abarnert

+0

這描述了IDispatch接口。它不使用GetProcAddress(),它使用DllGetClassObject() –

回答

1

爲每個真實函數編寫包裝函數。

例如

int addNumbers(int x, int y) { return x + y; } 

void addNumbersW(std::vector<VARIANT>& inArgs, std::vector<VARIANT>& outArgs) 
{ 
    // decode in args somehow 
    int x = getArg(inArgs, 0); 
    int y = getArg(inArgs, 1); 
    int r = addNumbers(x, y); 
    addArg(outArgs, r); 
} 

您可能會爲每個函數原型編寫一系列包裝函數,並簡化一些宏的使用。

+0

謝謝。我的想法與你在這裏的想法非常相似。我想我們可以只寫一個泛型函數,它將函數名稱作爲參數之一。通用函數會在內部打開函數名稱以調用正確的內部函數。 – windfly2006