Передача указателя в качестве аргумента подчиненному dll неправильного размера объекта

У меня есть два модуля. Один вызывает другой и передает в качестве аргумента структуру.

struct {
char* szDGRTag;
bool bTagEx;
} ADPTAG;

Мастер написан на C ++ с 98 года в Visual C ++ 6.0. Ведомый написан на C ++ 11 в Visual Studio 2010 Professional.
Функция, которая вызывается в Slave:

long lCheckPresenceOfFields (char* szName, ADPTAG* AdpTagList, long lNbVar)

В мастер:

long lNbVar = 2;
ADPTAG* AdpTagList = NULL;
AdpTagList = new ADPTAG[lNbVar];

AdpTagList[0].szTag = new char[32];
AdpTagList[0].bTagEx = true;
memset(AdpTagList[0].szTag, 0x0, 32+1);
AdpTagList[0].szTag = NULL;

AdpTagList[1].szTag = new char[32];
AdpTagList[1].bTagEx = true;
memset(AdpTagList[1].szTag, 0x0, 32+1);
AdpTagList[1].szTag = NULL;

int size = sizeof(AdpTagList[0]);
AdpTagList[0].szTag = "DDD";
AdpTagList[1].szTag = "AAA";

long pres = pGetFieldsPresence(szPath, AdpTagList, 2);

Я проверил размер AdpTagList [0] в Master, и он был 5 байтов, но в Slave это 8 байтов, поэтому первый объект в порядке, но любой следующий — плохо, потому что указатель указывает на неправильную область памяти.
В чем может быть проблема здесь? Другой компилятор? Вероятно, не так, как структура с только char * и int отлично работает между этими двумя модулями.
Независимо от размера первого объекта [0], секунда [1] является нулевым указателем.

2

Решение

Вы столкнулись с расхождением в упаковке. Вы можете изменить упаковку с помощью Опция компилятора «/ Zp».

Так как по умолчанию Visual Studio:

Пакетные структуры на 8-байтовых границах

Весьма вероятно, что ваш компилятор Visual Studio 2010 не определяет упаковку. Ваше приложение Visual C ++ 6.0, вероятно, определило 1-байтовую упаковку как структуру, содержащую int и char следует упаковать в это.

Использование 1-байтовой упаковки оптимизирует использование системной памяти программ, поскольку при заполнении памяти память не теряется.

Использование 8-байтовой упаковки оптимизирует скорость, поскольку увеличивает вероятность того, что структуры могут быть извлечены за одну загрузку.

Подробнее об упаковке вы можете прочитать здесь: https://msdn.microsoft.com/en-us/library/71kf49f1.aspx

Но я бы пошел с заявлением Microsoft:

Вы не должны использовать эту опцию, если у вас нет особых требований к выравниванию

То есть, поскольку вы должны изменить его, я бы рекомендовал изменить упаковку в приложении Visual C ++ 6.0.

3

Другие решения

Да, виновата разница в компиляторе. Нет никакой стандартизации C ++ на бинарном уровне. В частности, это означает, что любой компилятор может свободно выбирать свои собственные правила заполнения для структур, что и влияет на вас здесь. Очевидно, что более поздний компилятор решил добавить 3 байта заполнения, чтобы сделать структуру 64-битной, но старый компилятор этого не делает.

В общем случае нет способа обеспечить двоичную совместимость между данными, создаваемыми двумя разными компиляторами. Вы можете либо переключиться на использование потоков байтов, либо использовать один и тот же компилятор для обоих.

2

По вопросам рекламы [email protected]