You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从参数传递的函数提取参数及RunInMainThread多参数优化问询

Solution for Optimizing RunInMainThread with Parameter Binding and Variable Arguments (C03/CBuilder)

Let's break down how to fix both your issues: eliminating the need for the redundant fP1 parameter, and adding support for variable arguments—all without C++11 features like <functional> or lambdas.

1. Eliminate Redundant Parameter Passing

Your current code requires manually passing fP1 to initialize the struct's P1 field. We can use C++03 templates to automatically deduce the parameter type and bundle it with the closure function, no extra manual parameter setup needed.

Optimized Single-Parameter Version

template <typename TParam>
void Class2::RunInMainThread(void(__closure* FuncToCall)(TParam), TParam param) {
    struct Args {
        TParam P1;
        void(__closure* F)(TParam);
        void __fastcall FTC() { F(P1); }
    } args = {param, FuncToCall};
    TThread::Synchronize(NULL, &args.FTC);
}

Now you can call it cleanly, no need to worry about matching parameter types explicitly:

void Class1::MainThreadFunction(const __int64 param) {
    if(GetCurrentThreadId() != System::MainThreadID) {
        RunInMainThread(MainThreadFunction, param);
        return;
    }
    // ... rest of your main thread logic
}

The template automatically deduces TParam as const __int64, so you avoid repeating types and redundant parameter handling.

2. Add Support for Variable Arguments

Since C++03 doesn't have variadic templates, we'll implement overloaded versions of RunInMainThread for different argument counts (0, 1, 2, 3, etc.—extend as needed for your use case).

Full Overloaded Implementation

// 0-parameter version
void Class2::RunInMainThread(void(__closure* FuncToCall)()) {
    struct Args {
        void(__closure* F)();
        void __fastcall FTC() { F(); }
    } args = {FuncToCall};
    TThread::Synchronize(NULL, &args.FTC);
}

// 1-parameter version
template <typename T1>
void Class2::RunInMainThread(void(__closure* FuncToCall)(T1), T1 p1) {
    struct Args {
        T1 P1;
        void(__closure* F)(T1);
        void __fastcall FTC() { F(P1); }
    } args = {p1, FuncToCall};
    TThread::Synchronize(NULL, &args.FTC);
}

// 2-parameter version
template <typename T1, typename T2>
void Class2::RunInMainThread(void(__closure* FuncToCall)(T1, T2), T1 p1, T2 p2) {
    struct Args {
        T1 P1;
        T2 P2;
        void(__closure* F)(T1, T2);
        void __fastcall FTC() { F(P1, P2); }
    } args = {p1, p2, FuncToCall};
    TThread::Synchronize(NULL, &args.FTC);
}

// 3-parameter version (extend as needed for more arguments)
template <typename T1, typename T2, typename T3>
void Class2::RunInMainThread(void(__closure* FuncToCall)(T1, T2, T3), T1 p1, T2 p2, T3 p3) {
    struct Args {
        T1 P1;
        T2 P2;
        T3 P3;
        void(__closure* F)(T1, T2, T3);
        void __fastcall FTC() { F(P1, P2, P3); }
    } args = {p1, p2, p3, FuncToCall};
    TThread::Synchronize(NULL, &args.FTC);
}

How It Works

  • Each overload handles a specific number of arguments, matching the signature of the closure you want to run.
  • The nested Args struct captures both the closure function and its parameters, storing them until the main thread is ready to execute.
  • The FTC method acts as a trampoline: it invokes the saved closure with the stored parameters when TThread::Synchronize runs it on the main thread.

Key Notes

  • __closure is C++Builder-specific: This code relies on C++Builder's __closure keyword, which represents a member function pointer that includes the this pointer (a closure).
  • No C++11 required: All code uses only C++03 features, strictly adhering to your constraints.
  • Extensibility: Add more overloads if you need support for functions with more than 3 parameters.

内容的提问来源于stack exchange,提问作者Coder12345

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:44:17