【问题标题】:How to use GetProcAddress dynamically如何动态使用 GetProcAddress
【发布时间】:2012-06-06 21:12:15
【问题描述】:

我们知道,我们可以使用 GetProcAddress 从 DLL 句柄中获取函数指针,例如在 DLL 中定义的方法 foo:

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++ 中动态实现上述 callMethod?我能想到的唯一方法是我们必须将参数推送到堆栈然后调用 pFunc。我想那将是汇编语言。这里还有其他方法吗?我们还必须在这里处理不同的调用约定(stdcall、cdecl)。

【问题讨论】:

  • 对于某些调用约定,您需要一个程序集 thunk。例如,在 x64 上只有一个调用约定,它是一种快速调用约定,因此您必须能够注册参数。您可以在纯 C++ 中使用一些丑陋的转换来伪造大多数 x86 标准调用函数。
  • 作为另一种选择,您是否考虑过使用 COM(或 XPCOM)?因为你在很大程度上试图复制它的设计目的。除非您尝试在未编写为以这种方式访问​​的任意 DLL 上执行此操作,在哪种情况下……您从哪里获得有关 inputArguments 和 outputArguments 中的实际类型的信息?
  • 这描述了 IDispatch 接口。哪个使用GetProcAddress(),它使用DllGetClassObject()
  • C/C++ 语言不够强大,无法调用其原型在编译时未知的函数。
  • 非常感谢大家的回复。基本上我们的解决方案有 C++ 核心引擎和 Lua 脚本引擎。 DLL 方法将由知道确切方法签名的 Lua 脚本调用。但是,它需要通过不知道每个方法签名的核心引擎调用 DLL 方法。由于 DLL 是由我们编写的,因此 DLL 可以只公开一个 Invoke 方法,该方法将采用 VARIANT 类型的输入并返回类似于 IDispatch.Invoke 的 VARIANT 类型的输出。在 Invoke 方法内部,它会分派给特定的方法。

标签: c++ c winapi visual-c++ dll


【解决方案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 );
}

您可以为每个函数原型编写一系列包装函数,并通过一些宏来简化使用。

【讨论】:

  • 谢谢。我的想法与您在这里的想法非常相似。我认为我们可以只编写一个通用函数,它将函数名称作为参数之一。通用函数将在内部打开函数名称以调用正确的内部函数。
猜你喜欢
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多