Я пытаюсь пересылать нешаблоновые аргументы с переменным числом аргументов между двумя функциями. Ни одна из этих функций не принадлежит мне, поэтому я не могу изменить их подписи. Для этой цели я использовал va_args, но (к сожалению) мое решение не работает должным образом под MSVC. Вероятно, из-за перекрытия стека я получаю случайное значение, выбранное из стека.
Вот минимальный пример, воспроизводящий мою проблему. Функции funcA и funcB имеют ту же сигнатуру, что и функции из моей исходной задачи.
#include
int funcA(int a, void* b, ...)
{
va_list args;
va_start(args, b);
auto value = a + va_arg(args, int);
va_end(args);
return value;
}
int funcB(int a, void* b, ...)
{
va_list args;
va_start(args, b);
auto value = funcA(a, args);
va_end(args);
return value;
}
int main() {
return funcB(2, nullptr, 163);
}
Возможный вывод GCC:
Program returned: 165
Возможный вывод MSVC:
Program returned: 7731509
Вы можете запустить этот код здесь https://godbolt.org/z/Mjc8E3onW
Вышеупомянутое решение работает правильно и, как и ожидалось, в GCC, но в MSVC этот код возвращает мусорное число.
Я пытался настроить этот минимальный пример, явно определив соглашение о вызовах для __cdecl, но это не помогло. Я также пытался скомпилировать его, используя разные флаги оптимизации, но это ничего не изменило;
Обратите внимание, что я видел здесь много похожих вопросов, но ни один из них не ответил на мой вопрос, связанный с в MSVC.
Я проверил, как функция printf пересылает эти аргументы, но, к сожалению, она передает их в _vfprintf_s_l с помощью va_list, и это то, что я В моем случае не могу сделать.
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL _printf_s_l(
_In_z_ _Printf_format_string_params_(0) char const* const _Format,
_In_opt_ _locale_t const _Locale,
...)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
int _Result;
va_list _ArgList;
__crt_va_start(_ArgList, _Locale);
_Result = _vfprintf_s_l(stdout, _Format, _Locale, _ArgList);
__crt_va_end(_ArgList);
return _Result;
}
#endif
EDIT
Параметр b здесь auto value = funcA(a, args); был удален намеренно чтобы протестировать его под GCC. Даже если я верну его обратно, он не будет работать ни под GCC, ни под MSVC.
Моя настоящая/исходная проблема связана с перехватом функций. Мне нужно поместить перехватчик в функцию, экспортируемую .dll, с таким вариационным интерфейсом. Итак, когда я это делаю, я получаю код, который выглядит примерно так:
// orig::exported_func
// this is the original function exported by the .dll
// I don't have access to its implementation
//
// hook::exported_func
// this is my stub hook function. The hook is placed in runtime,
// by overriding the original function asm code. After hooking,
// original function address is stored inside orig::exported_func.
int hook::exported_func(int a, void* b, ...) {
// here is the place I need to forward this variadic arguments
// I dont even need to read them, the thing it to pass proper stack size
// Line below is just and example, it wont compile
auto retVal = orig::exported_func(a, b, ...);
.
.
.
// do some not related staff
.
.
.
return retVal;
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... under-msvc
Как правильно пересылать нешаблонные аргументы с переменным числом аргументов в C/C++ под MSVC ⇐ C++
Программы на C++. Форум разработчиков
1732058459
Anonymous
Я пытаюсь пересылать нешаблоновые аргументы с переменным числом аргументов между двумя функциями. Ни одна из этих функций не принадлежит мне, поэтому я не могу изменить их подписи. Для этой цели я использовал va_args, но (к сожалению) мое решение не работает должным образом под MSVC. Вероятно, из-за перекрытия стека я получаю случайное значение, выбранное из стека.
Вот минимальный пример, воспроизводящий мою проблему. Функции funcA и funcB имеют ту же сигнатуру, что и функции из моей исходной задачи.
#include
int funcA(int a, void* b, ...)
{
va_list args;
va_start(args, b);
auto value = a + va_arg(args, int);
va_end(args);
return value;
}
int funcB(int a, void* b, ...)
{
va_list args;
va_start(args, b);
auto value = funcA(a, args);
va_end(args);
return value;
}
int main() {
return funcB(2, nullptr, 163);
}
Возможный вывод GCC:
Program returned: 165
Возможный вывод MSVC:
Program returned: 7731509
Вы можете запустить этот код здесь https://godbolt.org/z/Mjc8E3onW
Вышеупомянутое решение работает правильно и, как и ожидалось, в GCC, но в MSVC этот код возвращает мусорное число.
Я пытался настроить этот минимальный пример, явно определив соглашение о вызовах для __cdecl, но это не помогло. Я также пытался скомпилировать его, используя разные флаги оптимизации, но это ничего не изменило;
Обратите внимание, что я видел здесь много похожих вопросов, но ни один из них не ответил на мой вопрос, связанный с в MSVC.
Я проверил, как функция printf пересылает эти аргументы, но, к сожалению, она передает их в _vfprintf_s_l с помощью va_list, и это то, что я В моем случае [b]не могу[/b] сделать.
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL _printf_s_l(
_In_z_ _Printf_format_string_params_(0) char const* const _Format,
_In_opt_ _locale_t const _Locale,
...)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
int _Result;
va_list _ArgList;
__crt_va_start(_ArgList, _Locale);
_Result = _vfprintf_s_l(stdout, _Format, _Locale, _ArgList);
__crt_va_end(_ArgList);
return _Result;
}
#endif
[b]EDIT[/b]
Параметр b здесь auto value = funcA(a, args); был удален намеренно чтобы протестировать его под GCC. Даже если я верну его обратно, он не будет работать ни под GCC, ни под MSVC.
Моя настоящая/исходная проблема связана с перехватом функций. Мне нужно поместить перехватчик в функцию, экспортируемую .dll, с таким вариационным интерфейсом. Итак, когда я это делаю, я получаю код, который выглядит примерно так:
// orig::exported_func
// this is the original function exported by the .dll
// I don't have access to its implementation
//
// hook::exported_func
// this is my stub hook function. The hook is placed in runtime,
// by overriding the original function asm code. After hooking,
// original function address is stored inside orig::exported_func.
int hook::exported_func(int a, void* b, ...) {
// here is the place I need to forward this variadic arguments
// I dont even need to read them, the thing it to pass proper stack size
// Line below is just and example, it wont compile
auto retVal = orig::exported_func(a, b, ...);
.
.
.
// do some not related staff
.
.
.
return retVal;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79205212/how-to-properly-forward-non-template-variadic-arguments-in-c-c-under-msvc[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия