Для решения проблемы в целом нужно знать:
- Соглашения о вызовах (эти stdcall , cdecl , fastcall , thiscall (кстати, последние два можно объединить в MSVC ++ ) и т. д.), которые управляют тем, как функции получают свои параметры (например, в специальных регистрах, в стеке, оба), как они возвращают значения (одинаковые) и что им разрешено удалять (например, некоторые регистры).
- Точные прототипы функций.
Вы можете найти все это только в символьной / отладочной информации, создаваемой компилятором, и (вероятно, в меньшей степени) в заголовочном файле, содержащем прототипы для функций в DLL. Есть одна проблема с заголовочным файлом. Если в нем не указано соглашение о вызовах, а функции были скомпилированы с соглашениями о вызовах, отличными от заданных по умолчанию (с помощью параметра компилятора), вам придется иметь дело с неоднозначностью. В любом случае вам нужно что-то проанализировать.
Если у вас нет этой информации, остается только один вариант - обратная инженерия DLL и / или ее пользователей.
Чтобы правильно вызывать произвольную функцию, зная только ее прототип и соглашение о вызовах во время выполнения, вам нужно создать код, аналогичный тому, который создается компилятором при вызове этой функции, когда она известна во время компиляции. Если вы решаете общую проблему, вам понадобится некоторый ассемблерный код, не обязательно написанный вручную, сгенерированный машинный код во время выполнения.
И последнее, но не менее важное: вам нужен код для генерации значений параметров. Это наиболее тривиально для числовых типов (целые числа, числа с плавающей запятой и т. П.) И их массивов, а наиболее сложно для структур, объединений и классов. Создание последнего на лету может быть по меньшей мере таким же сложным, как и правильное использование функций. Не забывайте, что они могут ссылаться на другие объекты, используя указатели и ссылки.
Общая проблема разрешима, но не дешево. Гораздо проще решить несколько простых конкретных случаев и, возможно, полностью избежать проблемы, переписав функции так, чтобы они содержали менее переменные параметры, и только одно соглашение о вызовах ИЛИ, написав для этого функции-оболочки.