У меня есть двухчастная программа, в которой основное ядро должно иметь зарегистрированный адаптер, а затем перезвонить в регистр. Части находятся в отдельных DLL, а ядро не знает особенностей адаптера (помимо методов и параметров раньше времени). Я попытался установить его с помощью следующего кода и ПОЛУЧИТЕ Segfault каждый раз, когда ядро пытается вызвать метод адаптера:Segfault при вызове виртуальной функции в другой DLL
Core.hpp/CPP (комбинированный и упрощенный):
class Core
{
public:
Core()
: mAdapter(NULL)
{ }
void DoStuff(int param)
{
if (this->mAdapter)
{
this->mAdapter->Prepare(param);
}
}
void Register(Adapter * adapter)
{
this->mAdapter = adapter;
}
private:
Adapter * mAdapter;
};
Adapter.hpp/CPP (в библиотеке ядра):
class Adapter
{
public:
Adapter(Core * core) { }
virtual void Prepare(int param)
{
// For testing, this is defined here
throw("Non-overridden adapter function called.");
}
};
AdapterSpecific.hpp/CPP (вторая библиотека):
class Adapter_Specific
: Adapter
{
public:
Adapter_Specific(Core * core)
{
core->Register(this);
}
void Prepare(int param) { ... }
};
Все классы и методы отмечены как экспорт DLL при построении первого модуля (ядра), а ядро помечено как экспорт, адаптер как импорт при построении адаптера.
Код работает до тех пор, пока не будет вызываться Core :: DoStuff. Пройдя через сборку, кажется, что она разрешает функцию из vftable, но адрес, в котором он заканчивается, равен 0x0013nnnn, а мои модули находятся в диапазоне 0x0084nnn и выше. Исходный отладчик Visual Studio и intellisense показывают, что записи в vftable одинаковы, а подходящий - на очень низкий адрес (один также переходит в 0xF-что-то, что кажется нечетным).
Редактирование для ясности: Выполнение никогда не вводится в класс или модуль адаптера. Предполагаемый адрес для вызова недействителен, и выполнение там теряется, что приводит к segfault. Это не проблема с каким-либо кодом в классе адаптера, поэтому я оставил это.
Я перестраивал обе библиотеки более одного раза в режиме отладки. Это чистый C++, ничего необычного. Я не уверен, почему это не сработает, но мне нужно перезвонить в другой класс и лучше избегать использования функции struct ptrs.
Есть ли способ использовать аккуратные обратные вызовы, подобные этому между модулями, или это как-то невозможно?
Почему люди загромождают код с помощью «this->»? – 2010-11-30 21:54:06
Это не фактический код, просто применимые части слегка переформулированы (структура не изменилась). Они находятся в некоторых частях реального кода, где это может быть неправильно прочитано. – ssube 2010-11-30 21:55:55
@VJo: явный всегда лучше, чем неявный – Falmarri 2010-11-30 21:56:20