【发布时间】: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