LINUX.ORG.RU

int64_t присвоение константы

 ,


1

1

Приветствую.

Наткнулся на странную ошибку. Пишу dll-ку на c++11 в qt-creator с mingw. Есть структура данных которая передается по указателю в функцию. Эта структура содержит переменную amount типа int64_t (пробовал long long, результат идентичен).

struct {
...
int64_t Amount;
...
};

Присваиваю этой переменной тестовое значение 1002:

...
Info->Amount = 1002;
...

Сторонняя программа (виндовая), которая использует мою dll, говорит что значение amount равно 4303557230592 (если присваивать не константу а int получаю тоже самое).

В процессе поиска ошибки декомпилировал мою dll, ida hex-rays показала:

...
*(_DWORD*)(a5 + 332) = 0;
*(_DWORD*)(a5 + 336) = 1002;
...

Посидел подумал.

Если конвертнуть 1002 в hex получится 3EA.

Если после этого числа добавить еще 8 нулей в hex (4 байта забитые 0-ми) то получим 0x3EA00000000. Если это число сконвертировать обратно в dec получим 4303557230592. Как раз то самое число, которое я получаю в сторонней программе.

Подскажите пожалуйста как такое вообще получается. И как мне без костылей сделать правильное присвоение в int64.

Линукс тут при том что сайт opensource.com а я использую опенсорсные технологии в проекте:)



Последнее исправление: ALeo (всего исправлений: 1)

Только что подумал, может быть я структуру неправильно описал и получил смещение на 4 байта для моей int64 переменной. Но я ее раз на 10 уже проверил. Может быть спека с ошибкой....

ALeo
() автор топика

Компилятор может сдвигать поля структуры для достижения нужного выравнивания типов данных. Сравни sizeof со значением, которого ты ожидаешь.

i-rinat ★★★★★
()

Чтобы не было выравниваний в структуре сделай

#PRAGMA PACK(PUSH, 1)
struct {
...
int64_t amount;
...
}
#PRAGMA PACK(POP)
dyb4hzvo
()

Дай угадаю. Собирает DLL один компилятор, а юзает другой?

Так или иначе, на выравнивание уже указали.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Верно. Надеялся что не придется связываться с msvc++. Mingw как-то привычней, почти gcc.

ALeo
() автор топика
Ответ на: комментарий от EXL

А если скомпилить dll'ку в MSVC++?

Да, надо будет проверить вечером.

ALeo
() автор топика
Ответ на: комментарий от invy

Кстати, ещё следует помнить, что Qt отказался от MinGW в пользу MinGW-w64. Это тоже накладывает интересный отпечаток на C++ ABI.

Увы, ALeo совершенно не предоставил информацию о используемых компиляторах как в его библиотеке, так и в программе.

EXL ★★★★★
()

Не открывай структуры пользователю. Просто объяви struct mystructure; и используй указатель на эту структуру. Сделай для каждой структуры ряд функций-геттеров вроде int64_t mystructure_amount_get(struct mystructure *structure); Ну и сеттеров, если нужно изменять структуру. Функции объяви с каким-нибудь стандартным способом вызова, вроде stdcall. Тогда проблем не будет.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от abs

Не на столько медленее, на сколько правильнее.

unt1tled ★★★★
()
Ответ на: комментарий от abs

Ну вообще во много раз медленнее. Если у тебя столько вызовов между библиотекой и приложением, что это становится проблемой, то стоит подумать об изменении интерфейса.

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

Legioner ★★★★★
()
Ответ на: комментарий от abs

Просто любопытно - на сколько это медленнее?

Отключенное выравнивание тоже замедление даст. Насколько - хз.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Legioner

Не открывай структуры пользователю

Не могу, я всего лишь реализую API из спеки, по которой должен возвращать структуру.

ALeo
() автор топика
Ответ на: комментарий от EXL

Сторонняя программа неизвестно чем скомпилена, возможно даже это Delphi, по крайней мере в спеке были примеры на нем.

Если я правильно понял, я использую i686-w64-mingw32-g++.exe (4.8.2)

ALeo
() автор топика
Ответ на: комментарий от EXL

MSVC++ ещё не пробовал?

В других «проектах» пробовал немного, плохо знаком с ним поэтому не стал использовать.

ALeo
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.