может баян и проблема тупа, но у меня чет не получилось нагуглить... есть класс, который реализует цпп-интерфейс над си-библиотекой FMOD... в си-библиотеке есть функция, которая загружает файл в память, декодирует его в wav и по завершении этого действа дергает калбек... в классе есть флажок (среди private членов), который должен быть выставлен в true, когда загрузка файла завершилась... калбек должен быть строго определенного вида... поэтому я не могу его сделать методом класса, так как никак не смогу неявно передать указатель this... если я делаю калбек friend функцией, то опять же, как калбек узнает члены какого именно экземпляра нужно менять, как передать указатель this не понятно... глобальной переменной так же не передашь, так как во-первых таких классов одновременно грузящих файлы может быть много, а во-вторых это какое-то коленное решение... что подскажите?)
Rel когда происходит вызов по передаваемым параметрам можно понять какому экземпляру принадлежит вызов? если да то сделать соответствие эти данные/указатель на класс.
к сожалению нет... тогда бы проблем не было... ну это как-то сложно... так как надо где-то хранить список всех экземпляров и проходить по нему... в классовою иерархию, которую я планировал не очень вкладывается... но как вариант...
Если экземпляров много, то массив функций. Каждая функция соответствует определённому экземпляру. Ну а если экземпляр один, то проблемы нет вовсе.
ну это как то странно слышится... экземпляров может быть от нескольких до нескольких десятков... все определяется в динамике... можно канещ дублировать функцию из секции кода куда-нить на выделенную страницу, подменять в функции константу указывающую на экземпляр и подставлять в адрес... но это слишком хакерское решение)
Rel нормальное решение, всего одни std::map, который статиком в этом же классе лежит, и все. Это не то что сложно, это тривиально. Это самый не хакерный способ, имхо. не как не влияет, все внутри класса, прозрачно по отношению к другим классам, наследование конечно может усложнить.
Rel Чтобы оно не было очень хакерским, объяви макрос и фигачь определённое кол-во функций, если будет мало - фигачь ещё. ^)
а, статиком... ясно... ну видимо больше вариантов то и нет... )) макросом не обойтись... тут динамическое количество, при компиляции не известное... а в статике расплодить n-ное количество функций - это будет слишком много кода имхо)
Rel Нормально решение, но если есть конечно какой-то другой признак, то конечно лучше сделать по-другому. Не бесконечное же. А несколько десятков маленьких функций, это ничто.
Booster да так то нормально, но придется динамично создавать новые функции ( как признак можно использовать ее адрес), а вот как их создавать это вопрос, тут будет явный хак не переносимый. С другим признаком как уже я сказал решение достаточно простое, и переносимое.
spa Опять же если у нас признак только адрес, то иначе никак не сделаешь. Динамично и не надо создавать, так как предел экземпляров как правило всё равно есть, этот предел и можно макросом зафигачить.
2Rel хак пойдет ? //rsdn.ru Код (Text): #include <windows.h> #pragma pack(push,1) struct _ProcThunk { DWORD m_mov; DWORD m_this; BYTE m_jmp; DWORD m_relproc; }; #pragma pack(pop) class ProcThunk { public: union { _ProcThunk thunk; }; void Init(void* proc, void* pThis) { thunk.m_mov = 0x042444C7; thunk.m_this = (DWORD)pThis; thunk.m_jmp = 0xe9; thunk.m_relproc = (int)proc - ((int)this+sizeof(_ProcThunk)); FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk)); } }; __declspec (naked) void* _cdecl pvoid_cast(...) { _asm { mov eax, [esp+4] ret } } class Thread { ProcThunk thunk_; public: DWORD Worker(void* p) { ::MessageBox("Thread", "Thread", 0, 0); return 0; } Thread() { thunk_.Init(pvoid_cast(Worker), (void*)this); } operator LPTHREAD_START_ROUTINE() { return (LPTHREAD_START_ROUTINE)&(thunk_.thunk); } }; int main(int argc, char* argv[]) { Thread t; HANDLE hThread = CreateThread(NULL, 0, t, NULL, 0, 0 ); WaitForSingleObject(hThread, INFINITE); return 0; } каллбек будет обычный метод а this будет на инстанс указывать
Rel Есть библиотечка sigc++ созданная специально для того, чтобы использовать методы классов как C-коллбеки.
ну может и пойдет, но грязноват он... ну вообще, если думать о сигналах... я пока еще не решил, какую гую буду использовать для этого проекта... либо gtkmm, либо qt, а может даже wxwidgets... в библиотеках есть свои методы работы с сигналами (а в gtkmm наверное и используется sigc++)... еще не думал, понадобится ли буст (в нем тоже вроде сигналы есть)... сигналы наверное хороший вариант...