2012-06-06 6 views
0

Как мы знаем, мы могли бы использовать GetProcAddress, чтобы получить указатель на функцию из DLL ручки, такие, как для метода обув определенной в DLL:Как использовать 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) 

Возможно ли реализовать описанный выше метод вызоваMethodDynamically на C/C++? Единственный способ, о котором я мог думать, это то, что нам нужно было бы вывести аргумент в стек, а затем вызвать pFunc. Думаю, тогда это был бы ассемблерный язык. Есть ли здесь другие способы? Нам также придется обрабатывать различные соглашения о вызовах (stdcall, cdecl).

+1

Для некоторых соглашений о вызовах вам понадобится сборка thunk. Например, на x64 существует только одно соглашение о вызове, и это соглашение fastcall, поэтому вы должны иметь возможность регистрировать аргументы. Вы можете подделать большинство функций stdcall x86 в чистом C++ с некоторыми уродливыми приведениями. –

+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

Смежные вопросы