Динамическая отправка методов, объявленных вне классов

Я пытаюсь понять реализацию библиотеки, но способ, которым некоторые методы динамически связаны, сбивает с толку меня.
Мне известны механизмы диспетчеризации при использовании объекта производного класса, но без объекта я понятия не имею, как он работает.
Библиотека, которую я пытаюсь понять, libitm из gcc.

Заголовочный файл libitm.h объявляет все методы ABI как методы верхнего уровня без класса или структуры вокруг них. И для большинства из них я нашел уникальное определение, поэтому у меня нет вопросов о них, и я опускаю их здесь. Но следующий отрывок показывает объявление 70 методов, определения которых сбивают меня с толку.

    typedef uint8_t  _ITM_TYPE_U1;
typedef uint16_t _ITM_TYPE_U2;
typedef uint32_t _ITM_TYPE_U4;
typedef uint64_t _ITM_TYPE_U8;
typedef float    _ITM_TYPE_F;
typedef double   _ITM_TYPE_D;
typedef long double _ITM_TYPE_E;
typedef float _Complex _ITM_TYPE_CF;
typedef double _Complex _ITM_TYPE_CD;
typedef long double _Complex _ITM_TYPE_CE;

#define ITM_BARRIERS(T) \
extern _ITM_TYPE_##T _ITM_R##T(const _ITM_TYPE_##T *) ITM_REGPARM;    \
extern _ITM_TYPE_##T _ITM_RaR##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
extern _ITM_TYPE_##T _ITM_RaW##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
extern _ITM_TYPE_##T _ITM_RfW##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
extern void _ITM_W##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM;   \
extern void _ITM_WaR##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM; \
extern void _ITM_WaW##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM;

ITM_BARRIERS(U1)
ITM_BARRIERS(U2)
ITM_BARRIERS(U4)
ITM_BARRIERS(U8)
ITM_BARRIERS(F)
ITM_BARRIERS(D)
ITM_BARRIERS(E)
ITM_BARRIERS(CF)
ITM_BARRIERS(CD)
ITM_BARRIERS(CE)

В файле dispatch.h объявляется структура abi_dispatch, которая используется в качестве базы для конкретных рассылок TM-алгоритмов. В этой структуре объявления 70 методов выше сделаны как чисто виртуальные методы. Следующий отрывок показывает макроопределение для методов и структуры.

#define ITM_READ_M(T, LSMOD, M, M2)                                         \
M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \
{                                                                         \
return load(ptr, abi_dispatch::LSMOD);                                  \
}

#define ITM_READ_M_PV(T, LSMOD, M, M2)                                      \
M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \
= 0;

#define ITM_WRITE_M(T, LSMOD, M, M2)                         \
M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \
_ITM_TYPE_##T val)  \
{                                                          \
store(ptr, val, abi_dispatch::LSMOD);                    \
}

#define ITM_WRITE_M_PV(T, LSMOD, M, M2)                      \
M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \
_ITM_TYPE_##T val)  \
= 0;

#define CREATE_DISPATCH_METHODS_T(T, M, M2) \
ITM_READ_M(T, R, M, M2)                \
ITM_READ_M(T, RaR, M, M2)              \
ITM_READ_M(T, RaW, M, M2)              \
ITM_READ_M(T, RfW, M, M2)              \
ITM_WRITE_M(T, W, M, M2)               \
ITM_WRITE_M(T, WaR, M, M2)             \
ITM_WRITE_M(T, WaW, M, M2)
#define CREATE_DISPATCH_METHODS_T_PV(T, M, M2) \
ITM_READ_M_PV(T, R, M, M2)                \
ITM_READ_M_PV(T, RaR, M, M2)              \
ITM_READ_M_PV(T, RaW, M, M2)              \
ITM_READ_M_PV(T, RfW, M, M2)              \
ITM_WRITE_M_PV(T, W, M, M2)               \
ITM_WRITE_M_PV(T, WaR, M, M2)             \
ITM_WRITE_M_PV(T, WaW, M, M2)

#define CREATE_DISPATCH_METHODS(M, M2)  \
CREATE_DISPATCH_METHODS_T (U1, M, M2) \
CREATE_DISPATCH_METHODS_T (U2, M, M2) \
CREATE_DISPATCH_METHODS_T (U4, M, M2) \
CREATE_DISPATCH_METHODS_T (U8, M, M2) \
CREATE_DISPATCH_METHODS_T (F, M, M2)  \
CREATE_DISPATCH_METHODS_T (D, M, M2)  \
CREATE_DISPATCH_METHODS_T (E, M, M2)  \
CREATE_DISPATCH_METHODS_T (CF, M, M2) \
CREATE_DISPATCH_METHODS_T (CD, M, M2) \
CREATE_DISPATCH_METHODS_T (CE, M, M2)
#define CREATE_DISPATCH_METHODS_PV(M, M2)  \
CREATE_DISPATCH_METHODS_T_PV (U1, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (U2, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (U4, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (U8, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (F, M, M2)  \
CREATE_DISPATCH_METHODS_T_PV (D, M, M2)  \
CREATE_DISPATCH_METHODS_T_PV (E, M, M2)  \
CREATE_DISPATCH_METHODS_T_PV (CF, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (CD, M, M2) \
CREATE_DISPATCH_METHODS_T_PV (CE, M, M2)

struct abi_dispatch
{
public:
enum ls_modifier { NONTXNAL, R, RaR, RaW, RfW, W, WaR, WaW };

public:
CREATE_DISPATCH_METHODS_PV(virtual, )
}

Производные структуры abi_dispatch можно найти, например, в Способ мл или же Метод-Г.Л.. Они используют CREATE_DISPATCH_METHODS (virtual) и вышеупомянутый макрос для генерации 70 методов чтения / записи и сопоставления их для загрузки / сохранения шаблонных функций.

Мой большой вопрос: как система во время выполнения узнает, какое определение метода (определение в method-gl или method-ml) следует использовать при вызове одной из библиотечных функций? В определении методов чтения / записи не упоминается объект abi_dispatch. В локальном хранилище потока присутствует объект abi-dispatch, но я не знаю, как это согласуется с этим.

Спасибо за помощь.

2

Решение

Нашел недостающую ссылку.

Есть еще один макрос (CREATE_DISPATCH_FUNCTIONS), который определяет 70 описаний функций сверху и вызывает соответствующие методы в объекте отправки.

2

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

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

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