Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / ABI динамических библиотек / 25 сообщений из 29, страница 1 из 2
27.01.2021, 19:50
    #40039463
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Насколько можно полагаться на то, что при передаче функции с соглашением stdcall
компиляторы расширяют короткие целые до размера платформы?

Предположим, у нас есть DLL, с экспортированной foo(short int) и приложение, её
использующее со значением -1. Мы делаем грязный трюк: подсовываем ему DLL, экспортирующую
foo(unsigned int). Можно ли полагаться на то, что новая DLL будет всегда получать от этого
приложения UINT_MAX, а не случайный мусор в старших битах или ещё хуже - поехавшие
параметры после данного?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.01.2021, 22:35
    #40039485
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Кажется short всегда был 16 разрядным. Это int может плавать.
...
Рейтинг: 0 / 0
27.01.2021, 23:03
    #40039492
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
maytonКажется short всегда был 16 разрядным.

Вопрос не в его собственной разрядности, а в том как он передаётся в функции динамических
библиотек с соглашением stdcall на платформах в 32 и 64 разряда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.01.2021, 23:16
    #40039493
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

maytonКажется short всегда был 16 разрядным.

Вопрос не в его собственной разрядности, а в том как он передаётся в функции динамических
библиотек с соглашением stdcall на платформах в 32 и 64 разряда.

Основной вопрос: накуа вы это делаете?

Ну и побочные вопросы:

- Алгоритм выравнивания аргументов при упаковке в стек.
- И как они (аргументы) копируются в стек.

Тут нужно читать стандарт. Но я не вижу оснований при копировании в стек поднимать short до int.
Не думаю, что это всё вообще имеет смысл обсуждать.
...
Рейтинг: 0 / 0
28.01.2021, 02:00
    #40039515
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov,

Можно полагаться на системное ABI.

AFAIK там никаких short int нет

https://en.wikipedia.org/wiki/X86_calling_conventions
...
Рейтинг: 0 / 0
28.01.2021, 07:28
    #40039532
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

Можно ли полагаться на то, что новая DLL будет всегда получать от этого
приложения UINT_MAX, а не случайный мусор в старших битах или ещё хуже - поехавшие
параметры после данного?
Выравнивание ABI гарантирует, следующие параметры не поедут. А вот старшие биты... Тут может зависеть от компилятора
Код: plaintext
1.
2.
3.
void __stdcall foo(short int);
extern short x[2];
void test() { foo(x[1]); }

gcc и clang выдают что-то такое
Код: plaintext
1.
2.
3.
4.
	pushl	%eax
	movswl	_x+2, %eax
	movl	%eax, (%esp)
	calll	foo
movswl - загрузка в регистр с расширением знака.
А вот у borland C по-другому
Код: plaintext
1.
2.
3.
	mov       ax,word ptr [_x+2]
	push      eax
	call      foo
и тут в старших битах кажется остался мусор.
...
Рейтинг: 0 / 0
28.01.2021, 11:05
    #40039583
teo609
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

Насколько можно полагаться на то, что при передаче функции с соглашением stdcall
компиляторы расширяют короткие целые до размера платформы?

Предположим, у нас есть DLL, с экспортированной foo(short int) и приложение, её
использующее со значением -1. Мы делаем грязный трюк: подсовываем ему DLL, экспортирующую
foo(unsigned int). Можно ли полагаться на то, что новая DLL будет всегда получать от этого
приложения UINT_MAX, а не случайный мусор в старших битах или ещё хуже - поехавшие
параметры после данного?

Приложение в точке вызова положит в стек то, что описано в точке вызова. "приложение, её использующее со значением -1" - если за этим стоит нормальный вызов "foo(short int)" то в стек должны пойти 2 байта, а если их читать функцией "foo(unsigned int)" то она возьмет из стека 4 байта. Но, по идее GetProcAddress должен не найти foo(short int) и до вызова не дойдет.
...
Рейтинг: 0 / 0
28.01.2021, 14:09
    #40039632
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
petravОсновной вопрос: накуа вы это делаете?

Разработка новой версии библиотеки с расширенным функционалом, но сохранением обратной
совместимости как на уровне исходников, так и двоичной.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.01.2021, 14:13
    #40039633
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Надежнее сделать два билд-скрипта. Чтоб собирались фолдеры типa x86, x64 для каждой разрядности.

Ну а в приложении набить "гвоздей" макросами.
...
Рейтинг: 0 / 0
28.01.2021, 14:19
    #40039636
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Приложения чужие, в них ничего не набьёшь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.01.2021, 15:22
    #40039664
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
teo609
Dimitry Sibiryakov

Насколько можно полагаться на то, что при передаче функции с соглашением stdcall
компиляторы расширяют короткие целые до размера платформы?

Предположим, у нас есть DLL, с экспортированной foo(short int) и приложение, её
использующее со значением -1. Мы делаем грязный трюк: подсовываем ему DLL, экспортирующую
foo(unsigned int). Можно ли полагаться на то, что новая DLL будет всегда получать от этого
приложения UINT_MAX, а не случайный мусор в старших битах или ещё хуже - поехавшие
параметры после данного?

Приложение в точке вызова положит в стек то, что описано в точке вызова. "приложение, её использующее со значением -1" - если за этим стоит нормальный вызов "foo(short int)" то в стек должны пойти 2 байта, а если их читать функцией "foo(unsigned int)" то она возьмет из стека 4 байта. Но, по идее GetProcAddress должен не найти foo(short int) и до вызова не дойдет.
Вот только бред писать не надо, ни в зуб ногой в теме
...
Рейтинг: 0 / 0
28.01.2021, 17:10
    #40039686
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Barlone
Dimitry Sibiryakov

Можно ли полагаться на то, что новая DLL будет всегда получать от этого
приложения UINT_MAX, а не случайный мусор в старших битах или ещё хуже - поехавшие
параметры после данного?
Выравнивание ABI гарантирует, следующие параметры не поедут.

А если в аргументах только N аргументов типа short и всё, то они все выровняются по границе sizeof(int)?
Всё что меньше int выравнивается в стеке по sizeof(int)?
...
Рейтинг: 0 / 0
28.01.2021, 21:48
    #40039734
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

petravОсновной вопрос: накуа вы это делаете?

Разработка новой версии библиотеки с расширенным функционалом, но сохранением обратной
совместимости как на уровне исходников, так и двоичной.

А следующим шагом захочется добавить ещё один аргумент. А для старой программы, которая не
знает об этом аргументе, использовать значение по умолчанию. И придётся писать промежуточную
DLL, которая будет типы преобразовывать и значения по умолчанию подставлять.

Я бы сразу писал эту прокси-DLL. Мог бы переупорядочить аргументы под новые мысле-пожелания.
...
Рейтинг: 0 / 0
28.01.2021, 22:16
    #40039745
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Что-то вспомнилось, есть в WinAPI (GDI) одна волшебная функция. Сигнатура у неё упрощённо такая:

Код: plaintext
1.
void MyFunc(MY_STRUCT *);


При этом в структуре MY_STRUCT первое поле — это размер структуры типа UINT. Этот размер структуры
является по совместительству идентификатором типа структуры. Туда можно подставить другую структуру
типа MY_STRUCT_EX. Во талант костыли прикручивать, я был очень удивлён.

Вопрос в том, когда функция проектировалась до придумывания костыля, то зачем они первым полем
прописали размер структуры? Ну понятно, что для некоторой дополнительной безопасности. Но… эээ.
...
Рейтинг: 0 / 0
28.01.2021, 22:38
    #40039749
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Если сравнивать с указателями.

Вместо HANDLE сложнее впихнуть другой HANDLE. Ну тоесть использовать имеющийся можешь,
а создать новый хендл - через специальный API.
...
Рейтинг: 0 / 0
28.01.2021, 22:53
    #40039752
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
mayton
Если сравнивать с указателями.

Вместо HANDLE сложнее впихнуть другой HANDLE. Ну тоесть использовать имеющийся можешь,
а создать новый хендл - через специальный API.

HANDLE — это указатель (или индекс) на структуру в памяти ядра ОС. Я уверен там штатно записан тип
этого дескриптора, а не размер как тип. Это немного другое. Это не костыль. В моём примере была
обычная структура клиентского кода.

Впрочем, HANDLE как некая универсальная штука, которая ссылается на всё что угодно тоже смотрится
диковато. Как-то неправильно…
...
Рейтинг: 0 / 0
28.01.2021, 23:03
    #40039755
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
petravВопрос в том, когда функция проектировалась до придумывания костыля, то зачем они первым
полем прописали размер структуры?

Именно для того, чтобы её можно было расширять. Ты не поверишь, но есть люди, которые
думают наперёд.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.01.2021, 23:12
    #40039757
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

petravВопрос в том, когда функция проектировалась до придумывания костыля, то зачем они первым
полем прописали размер структуры?

Именно для того, чтобы её можно было расширять. Ты не поверишь, но есть люди, которые
думают наперёд.

Если бы эти люди думали наперёд, то они бы в первом поле структуры прописали бы идентификатор типа
структуры, а не воспринимали бы потом размер структуры как id. В том то и дело.
...
Рейтинг: 0 / 0
28.01.2021, 23:39
    #40039762
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

petravВопрос в том, когда функция проектировалась до придумывания костыля, то зачем они первым
полем прописали размер структуры?

Именно для того, чтобы её можно было расширять. Ты не поверишь, но есть люди, которые
думают наперёд.

Кроме того мой пример — это исключение в проектировании WinAPI. Обычно они имеют функцию аля ::CreateRemoteThread(), а потом
добавляют функцию ::CreateRemoteThreadEx(). Т.е. это был явный костыль, а не думанье наперёд.
...
Рейтинг: 0 / 0
29.01.2021, 00:04
    #40039768
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
petrav

Впрочем, HANDLE как некая универсальная штука, которая ссылается на всё что угодно тоже смотрится
диковато. Как-то неправильно…

Почему неправильно?
...
Рейтинг: 0 / 0
29.01.2021, 01:31
    #40039777
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
petravКроме того мой пример — это исключение в проектировании WinAPI.

Значит ты просто с ним совсем не знаком. Там такую структуру имеет каждая вторая структура
если не первая. Размер работает лучше идентификатора версии поскольку даже структуру
неизвестной версии функция может корректно обработать. Например, сериализовать и переслать
кому-нибудь другому.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.01.2021, 01:53
    #40039783
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

petravКроме того мой пример — это исключение в проектировании WinAPI.

Значит ты просто с ним совсем не знаком.
Очень может быть.

Dimitry Sibiryakov
Там такую структуру имеет каждая вторая структура
если не первая.

Размер структуры в первом поле действительно часто используется в WinAPI. Но редко как идентификатор.
Например, в ::CreateProcess() я вижу совсем другую логику, хотя размер структуры там присутствует.

Dimitry Sibiryakov
Размер работает лучше идентификатора версии поскольку даже структуру
неизвестной версии функция может корректно обработать. Например, сериализовать и переслать
кому-нибудь другому.

И часто функции WinAPI могут принять структуру неизвестного размера, потом не распознав её они обязаны её
куда-то переслать или сереализовать? Например, ::CreateProcess() не распознал структуру, но зато её сериализовал и
переслал. И типа всё круто? Гибкость же.

Вы перепутали идентификацию, проверку размера и целепологание.
...
Рейтинг: 0 / 0
29.01.2021, 02:27
    #40039788
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
Dimitry Sibiryakov

petravКроме того мой пример — это исключение в проектировании WinAPI.

Значит ты просто с ним совсем не знаком. Там такую структуру имеет каждая вторая структура
если не первая. Размер работает лучше идентификатора версии поскольку даже структуру
неизвестной версии функция может корректно обработать. Например, сериализовать и переслать
кому-нибудь другому.

+1

Мысль интересная. Это похоже на процессинг XML, когда вы встретили новый неизвестный тег
но не упали с ошибкой а спокойно поскипали и пошли дальше.

Это кстати очень хорошо согласуется с философией сетевых протоколов. Быть маскимально
консервативным при сериализации и максимально либеральным при парсинге.
...
Рейтинг: 0 / 0
29.01.2021, 08:34
    #40039811
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
...
Рейтинг: 0 / 0
29.01.2021, 11:39
    #40039849
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ABI динамических библиотек
mayton
Dimitry Sibiryakov

пропущено...

Значит ты просто с ним совсем не знаком. Там такую структуру имеет каждая вторая структура
если не первая. Размер работает лучше идентификатора версии поскольку даже структуру
неизвестной версии функция может корректно обработать. Например, сериализовать и переслать
кому-нибудь другому.

+1

Мысль интересная. Это похоже на процессинг XML, когда вы встретили новый неизвестный тег
но не упали с ошибкой а спокойно поскипали и пошли дальше.

Это кстати очень хорошо согласуется с философией сетевых протоколов. Быть маскимально
консервативным при сериализации и максимально либеральным при парсинге.

Угу... Тут мы не можем ничего скипать и идти спокойно дальше. Программа должна работать
корректно, а не как получится.

То что размер структуры используется что бы повысить вероятность обнаружения сбоя — это понятно.
Костылём является использование размера как идентификатора. Вот в ::CreateProcess() такого
косяка нет, там действительно люди подумали заранее.

MSDNlpStartupInfo

A pointer to a STARTUPINFO or STARTUPINFOEX structure.

To set extended attributes, use a STARTUPINFOEX structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / ABI динамических библиотек / 25 сообщений из 29, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]