Вернуть обратно Vector

Accelerator

Участник
Сообщения
71
Реакции
17
При написании натива для расширения столкнулся с проблемой. Функцию, которую вызываю, содержит 4 аргумента и поинтер. Последний, 4й аргумент - векторный. После выполнения функции, он изменяется на нужные значения. В линуксе натив работает, а вот в винде - нет.

C-подобный:
cell_t L4D2_GetRandomSpawnPosition(IPluginContext *pContext, const cell_t *params)
{
    if (g_pZombieManager == NULL)
    {
        return pContext->ThrowNativeError("ZombieManager unsupported or not available; file a bug report");
    }

    static ICallWrapper *pWrapper = NULL;

    if (!pWrapper)
    {
        REGISTER_NATIVE_ADDR("GetRandomSpawnPosition",
            PassInfo pass[4]; \
            pass[0].flags = PASSFLAG_BYVAL; \
            pass[0].size = sizeof(ZombieClassType); \
            pass[0].type = PassType_Basic; \
            pass[1].flags = PASSFLAG_BYVAL; \
            pass[1].size = sizeof(int); \
            pass[1].type = PassType_Basic; \
            pass[2].flags = PASSFLAG_BYVAL; \
            pass[2].size = sizeof(CBaseEntity *); \
            pass[2].type = PassType_Basic; \
            pass[3].flags = PASSFLAG_BYVAL; \
            pass[3].size = sizeof(Vector*); \
            pass[3].type = PassType_Basic; \
            pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4));
    }

    int client = params[3];
    CBaseEntity * pClient = NULL;
    if (client != -1)
    {
        pClient = UTIL_GetCBaseEntity(client, true);
        if(pClient == NULL)
        {
            return pContext->ThrowNativeError("Invalid client entity");       
        }
    }

    Vector vector;
    vector[0] = sp_ctof(0.0);
    vector[1] = sp_ctof(0.0);
    vector[2] = sp_ctof(0.0);

    unsigned char vstk[ sizeof(void*) + sizeof(ZombieClassType) + sizeof(int) + sizeof(CBaseEntity *) + sizeof(Vector*) ];
    unsigned char *vptr = vstk;

    *(void **)vptr = g_pZombieManager;
    vptr += sizeof(void *);
   
    *(cell_t*)vptr = params[1];
    vptr += sizeof(ZombieClassType);

    *(int *)vptr = params[2];
    vptr += sizeof(int *);

    *(CBaseEntity **)vptr = pClient;
    vptr += sizeof(CBaseEntity *);

    *(Vector**)vptr = &vector;

    pWrapper->Execute(vstk, NULL);

    const void *buffer = (const unsigned char *)vstk + pWrapper->GetParamInfo(3)->offset;

    Vector *v = NULL;
    v = *(Vector**)buffer;

    cell_t* addr;
    pContext->LocalToPhysAddr(params[4], &addr);

    addr[0]=sp_ftoc(v->x);
    addr[1]=sp_ftoc(v->y);
    addr[2]=sp_ftoc(v->z);
    return 0;
}
Падение происходит при вызове pWrapper->Execute(vstk, NULL);
Как можно вернуть значения вектора обратно, по примеру флага SDKTools VENCODE_FLAG_COPYBACK?
Если собирать вызов через SDKTools, то он работает как в линуксе, так и в винде, но мне нужно заставить его работать в расширении как натив.

*(Vector**)vptr = NULL; - в этом случае падения нет, но Vector возвращается как NULL.
По сути, в функцию нужно передавать только переменную, в которую запишутся нужные значения, сама она не должна содержать каких-либо значений.
 
Последнее редактирование:

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
Наверно будет лучше тебе об этом спросить на форумах по с++. Например тут или тама.
А здесь лучше написал бы урок, как ты умудрился настроить среду разработки под source SDK. Я думаю многие были-бы тебе благодарны. Я то точно.
 
Сверху Снизу