почему новая виртуальная функция не нарушит бинарную совместимость для каждого явления?

Я изучаю бинарную совместимость на основе этого KDE вики, и посмотри что

добавить виртуальную функцию к классу, который не имеет виртуальных функций или виртуальных баз

нарушит совместимость. Тогда я попробовал.

Предположим, я хочу создать FastString.dll предоставить, и вот определение.

//FastString.h

#ifdef _DLL_EXPORT
#define LIB_EXPORT __declspec(dllexport)
#else
#define LIB_EXPORT __declspec(dllimport)
#endif

class LIB_EXPORT FastString
{
public:
FastString(void);
~FastString(void);

int length();

private:
int m_len;
unsigned char *m_bytes;
};

и реализация

//FastString.cpp
#include "FastString.h"
FastString::FastString(void)
{
m_len = 0;
}

FastString::~FastString(void)
{
}

int FastString::length()
{
printf("Function of length, string len is %d\n", m_len);
return m_len;
}

Пока в третьем exe файле test.exe, используется FastString, как показано ниже

// main.cpp

#include <conio.h>
#include "FastString.h"
int _tmain(int argc, _TCHAR* argv[])
{
FastString str;
str.length();

printf("Please input any key to exit...");
_getch();
return 0;
}

Пожалуйста, обратите внимание: в main.cpp включенный FastString.h это другой файл, когда я добавил виртуальную функцию в FastString, модификация находится под FastString.dll.

Они находятся в одном решении (компилятор: VS2012) и успешно собраны. После этого я добавляю новую виртуальную функцию в FastString.h.

virtual bool isEmpty();

И в FastString.cpp я реализую это с простым возвратом

bool FastString::isEmpty()
{
return false;
}

Затем я строю FastString.dll индивидуально и перезапускаю test.exe. Вывод такой же, как и предыдущий, без ошибок.
Так, почему это поведение не нарушает бинарную совместимость?
В моем понимании, экземпляр str должен иметь виртуальные таблицы указатель, и расположение памяти должно быть изменено.
Я также имел отладку на основе инструмента VS и нашел str еще не было _vptr, это значит виртуальные таблицы создается под компилятор период, а не в ссылка на сайт период?

0

Решение

Вызов не виртуальной функции FastString::length() не зависит от компоновки, и эта функция, определяемая в DLL, знает фактическую компоновку объекта и находит правильного члена. Вы должны быть поражены несовместимости макета, сделав m_len публичный и доступ к нему извне DLL.

Хотя не существует общего правила о том, где находится VMT, он обычно создается компилятором и помещается в какой-то определенный модуль перевода (* .obj), то есть там, где определена первая виртуальная функция. Иногда, когда, например, все виртуальные функции встроены, необходимо применять более продвинутые стратегии, которые обычно включают компоновщик. Но, как правило, при использовании более старого компилятора заголовка будет недостаточно подсказок, связанных с наличием VMT, и он не будет создавать указатель VMT для этого объекта.

0

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector