从GetProcAddress强制转换的函数的签名必须完全匹配吗?
Does the signature of the function casted from GetProcAddress have to match exactly?
这个问题基本上可以归结为"我可以安全地将函数指针强制转换为具有可转换为这些类型的参数的指针吗?",但如果没有实际示例,这听起来非常可疑。
我做了一个小的实用程序函数从DLL中调用一些东西,给定DLL名称,函数名称,适当的返回类型,参数类型和参数。但是,在使用此实用程序时,可能会出现超出所需的额外膨胀。我想知道不显式指定参数类型是否安全。以Windows API MessageBoxW
为例:
callStdcallDllFunction<int, HWND, PCWSTR, PCWSTR, UINT>(
L"user32", "MessageBoxW", nullptr, nullptr, nullptr, 0
);
这里我显式地指定了MessageBoxW
的返回类型和四个参数类型。当然,如果参数从右开始,与函数中的类型相同,我就不需要指定它们。但是,只要首先传递给函数的参数是有效的(这些都是),就可以推断类型吗?
callStdcallDllFunction<int>(L"user32", "MessageBoxW", nullptr, nullptr, nullptr, 0);
在这里,我相信GetProcAddress
的结果将被铸造到int(__stdcall *)(std::nullptr_t, std::nullptr_t, std::nullptr_t, int);
。不过,传入的参数仍然适合实际的函数。这仍然是定义良好的行为吗?它总是做我想做的吗?到目前为止,每次我测试它都是有效的。
当我在它,它是可以离开返回类型作为void
,如果它是未使用的?
//return type is void instead of the actual int
callStdcallDllFunction(L"user32", "MessageBoxW", nullptr, nullptr, nullptr, 0);
据我所知,每次我都试过了。如果这些确实保证工作,我希望能够像这样使用它们,但我真的不知道它们是否总是有效,而且我不打算冒我所写的未定义行为的风险。
确切的代码与问题无关,但是您可以在这里找到可以用于测试的stdcall版本(例如MessageBox
是什么)。这些版本与cdecl版本之间的唯一区别是在函数签名中添加了__stdcall
。
您必须知道调用约定的确切细节,以及过去能够给出精确答案的ABI。
在某些调用约定中,参数在堆栈上传递。只要参数的大小相同,并且不涉及额外的转换,就不会有崩溃的风险。返回值:如果在堆栈上返回,要小心。如果它返回到寄存器中,那就无关紧要了。
通常具有相同长度的类型不是问题。但是要小心一些更奇特的类型,比如成员(函数)指针,它们不一定和void*一样大。
可转换性不够严格。char可以转换为long类型,但在堆栈上它们占用的字节数不同,因此这样的函数指针强制转换会导致不同的堆栈内容解释。
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- GetProcAddress vs __declspec( dllimport )
- 'dll_file'可以是"0":这不符合函数的规范'GetProcAddress'
- 如何将 GetProcAddress 与 JNA 一起使用?
- GetProcAddress 无法正常工作
- 从 GetProcAddress 获取的函数指针在使用 stdlib 时会使程序崩溃
- 如何使用 WinDbg 查找"GetProcAddress"函数的进程名称
- GetProcAddress fails
- 在 GetProcAddress 的 lpProcName 中是否有 DLL 函数修饰的参考
- 为什么传统的 GetProcAddress 到 std::function 并不简单
- 为什么 GetProcAddress 在实现时会引发异常
- GetProcAddress 在 c++ 中返回错误代码 127
- 如何在没有类型转换的情况下使用getProcAddress()
- C++ GetProcAddress 64 位返回 32 位地址
- 指向多个参数的函数指针 C++11 std::function:模板化 GetProcAddress
- 铸造getProcaddress在C 中返回指针
- getProcAddress()为我的Hello World功能返回null
- getprocaddress的类似函数使用结构
- IIS:在 ISAPI 筛选器上调用 GetProcAddress 失败
- getProcAddress - NULL is returned