Вопрос в значительной степени сводится к «Могу ли я безопасно использовать указатель на функцию с параметрами, конвертируемыми в эти типы?», Но это звучит крайне подозрительно без практического примера.Соответствует ли подпись функции, полученной из GetProcAddress?
Я сделал небольшую функцию полезности для вызова чего-либо из 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
), которые вы можете использовать для тестирования here. Единственная разница между ними и версиями cdecl заключается в добавлении __stdcall
в подпись функции.
Ну, единственные варианты, которые я предоставил, были stdcall и cdecl. У этих двух есть разница в том, как очищается стек. Если мне приходится иметь дело с типом размеров, я, вероятно, не буду утруждать себя отсутствием типов, когда он будет работать для этого вызова, но не другой. – chris
http://stackoverflow.com/a/12465133/59019 – jmihalicza