Я стремлюсь уменьшить размер файла DLL, которую я пишу (Windows, MSVC).
У меня очень большое количество (> 10000) функций, которые нужно экспортировать. В настоящее время я делаю это с файлом .DEF и экспортирую через порядковый номер (так как экспорт по имени значительно увеличит размер файла).
В любом случае экспортируемые функции выглядят так:
#define MK_FUNC(i) extern "C" T_RESULT* export##i(T_ARG* arg0, ...) \
{ \
va_list va; \
va_start(va, arg0); \
auto result = DoSomeWork( ##i, arg0, va ); \
va_end(va); \
return result; \
} \
MK_FUNC(0);
MK_FUNC(1);
MK_FUNC(2);
// ....
Теперь каждая декларация экспорта ## i по-прежнему содержит довольно много - почти идентичных - инструкций, что приводит к значительным накладным расходам на размер моей DLL, поэтому я пытаюсь выяснить, могу ли я уменьшить это дальше.
Thunking пришел в голову; это несколько усложняется дополнительным параметром идентификации, передаваемым в DoSomeWork () (## 1 - хотя это может быть любой уникальный идентификатор исходной функции, так же как и его адрес или любой другой символ).
thread_local int functionId;
T_RESULT* ThunkedCall(T_ARG* arg0, ...)
{
va_list va;
va_start(va, arg0);
auto result = DoSomeWork( functionId, arg0, va );
va_end(va);
return result;
}
#define MK_FUNC(i) extern "C" T_RESULT* export##i(T_ARG* arg0, ...) \
{ \
function_id = ##i; \
// .. now somehow "jmp" to ThunkedCall
}
MK_FUNC(0);
MK_FUNC(1);
// ....
Может ли это вообще сработать? И если так - как я могу реализовать переход к ThunkedCall?
Я полагаю, что обычный вызов функции исключен из-за переменных аргументов (также может быть немного медленнее, но это не главная проблема).
Возможно, мне просто нужно что-то вроде инструкции asm "jmp" здесь? Но опять же, нет встроенной сборки под x64 с MSVC, поэтому я немного растерялся, как мне это реализовать.
Спасибо!