То, что у вас уже есть, является правильным (и единственным) способом решения этой ситуации в «классических» (до C ++ 11) компиляторах C ++ Builder.
Чтобы поддерживать переменное количество параметров, вам придется использовать несколько перегрузок, другого варианта нет (без погружения в низкоуровневую встроенную сборку для настройки стеков вызовов вручную, но даже в этом случае он может работать некорректно во всех границы потоков), например:
void Class1::MainThreadFunction()
{
if (GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction);
return;
}
//...
}
void Class1::MainThreadFunction(const __int64 param)
{
if(GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction, param);
return;
}
//...
}
// and so on as needed ...
template<typename FuncType>
void Class2::RunInMainThread(FuncType FuncToCall)
{
struct {
FuncType F;
void __fastcall FTC() { F(); }
} Args = {FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType param)
{
struct {
const ParamType &P;
FuncType F;
void __fastcall FTC() { F(P); }
} Args = {param, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType1, typename ParamType2>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType1 param1, const ParamType2 param2)
{
struct {
const ParamType1 &P1;
const ParamType2 &P2;
FuncType F;
void __fastcall FTC() { F(P1, P2); }
} Args = {param1, param2, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
// and so on as needed...
Если вы просматриваете различные заголовочные файлы RTL, такие как sysvari.h
и utilcls.h
, использование перегрузок - это то, как сама Borland подходит к вопросу о переменном количестве параметров в нескольких своих собственных API, иногда свыше 30+ параметров, этого более чем достаточно для обработки большинства пользовательских кодов.