Итак. Все мне известные - *кроме* FARа - системы экспортируют свои интерфейсы по схеме типа vtbl. Типичный пример - Microsoft COM. Т. е. интерфейс - это таблица указателей на функции, каждая из которых первым (возможно, скрытым) параметром имеет указатель на саму эту таблицу.
У функций FARа такого первого параметра нет. Казалось бы, все правильно, он же все равно не используется, но почему же Microsoft (и все остальные) его оставляют? Только ли для того, чтобы быть бинарно совместимыми с C++-ными объектами? Оказывается, такая схема дает еще одно важное преимущество. Если я захочу превратить указатель на функцию из интерфейса FARa в обычную C-функцию, у меня получится, например так:
Code: Select all
void WINAPI FarRecursiveSearchReified(FARSTANDARDFUNCTIONS *this, const wchar_t *InitDir, const wchar_t *Mask, FRSUSERFUNC Func, DWORD Flags, void *Param) {
this->FarRecursiveSearch(InitDir, Mask, Func, Flags, Param);
}
Code: Select all
void WINAPI FarRecursiveSearchReified(FARSTANDARDFUNCTIONS *this, const wchar_t *InitDir, const wchar_t *Mask, FRSUSERFUNC Func, DWORD Flags, void *Param) {
this->FarRecursiveSearch(this, InitDir, Mask, Func, Flags, Param);
}
Code: Select all
movl 4(%esp), %eax
jmp *xxx(%eax)
Для людей, которые пишут плагины на C/C++ это не нужно. Но например, если писать на Хаскелле, во втором варианте делать это будет намного проще, а сам код будет работать быстрее. Думаю, это справедливо и для других языков, имеющих стандартный FFI к С.