将C函数转换为C#

时间:2017-01-29 20:38:03

标签: c# c

我正在寻找关于是否可以将此功能从C转换为C#的一些指导。

功能是:

int parseClientPacket(byte * packet_data, u32 packet_size, int is_start_of_packet, u32 header_size, u32 num_to_parse, const u16 * type_map, const u16 * size_map, ...)
{
    const u32   common_size_map[]   = { 0x01, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x04, 0x0C, 0x40, 0x08, 0x00, 0x06, 0x02 };
    byte        *data               = 0;
    u32         pflag               = 0;
    u32         flag                = 1U << 0;;
    u32         num_parsed          = 0;
    int         ret                 = 0;
    va_list     args;

    va_start(args, size_map);

    if (header_size == 0)
    {
        goto done;
    }

    if (is_start_of_packet == 0)
    {
        data = packet_data + header_size + 2;

        if (header_size >= 4)
        {
            pflag = *(u32*)(packet_data + 2);
        }
        else if (header_size >= 3)
        {
        }
        else if (header_size == 2)
        {
            pflag = *(u16*)(packet_data + 2);
        }
        else
        {
            pflag = packet_data[2];
        }
    }
    else
    {
        data = packet_data + header_size + 9;

        if (header_size >= 4)
        {
            pflag = *(u32*)(packet_data + 9);
        }
        else if (header_size >= 3)
        {
        }
        else if (header_size >= 2)
        {
            pflag = *(u16*)(packet_data + 9);
        }
        else
        {
            pflag = packet_data[9];
        }
    }

    if (num_to_parse == 0)
    {
        return 1;
    }

    for (u32 i = 0; i < num_to_parse; i++, flag <<= 1)
    {
        void    **arg = va_arg(args, void**);
        u16     size;

        if (pflag & flag)
        {
            if (is_start_of_packet && data > packet_data + packet_size)
            {
                return 0;
            }

            if (type_map[i] == 0x0C)
            {
                if (size_map[i] <= 1)
                {
                    size = *(u16*)data;

                    if (arg)
                    {
                        *arg = (void*)data;
                    }
                    data = data + size + 2;
                }
                else
                {
                    byte num_blocks = *data++;
                    size            = 0;

                    for (u32 i = 0; i < num_blocks; i++, data = data + size + 2)
                    {
                        size = *(u16*)data;

                        if (arg)
                        {
                            *arg = (void*)data;
                        }
                    }
                }
            }
            else if (type_map[i] == 0x0D)
            {
                u32 *arg_sz = va_arg(args, u32*);
                size        = *(u16*)data;

                if (arg)
                {
                    *arg = (void*)(data + 2);
                }
                if (arg_sz)
                {
                    *arg_sz = size;
                }
                data    = data + size + 2;

                if (is_start_of_packet && data > packet_data + packet_size)
                {
                    return 0;
                }
            }
            else if (type_map[i])
            {
                u16 size = common_size_map[type_map[i]] * size_map[i];

                if (is_start_of_packet && data + size > packet_data + packet_size)
                {
                    return 0;
                }

                if (arg)
                {
                    mg_memcpy((void*)arg, data, size);
                }
                data = data + size;
            }
            else
            {
                if (arg)
                {
                    *arg = (void*)data;
                }
                data = data + (common_size_map[type_map[i]] * size_map[i]);

                if (is_start_of_packet && data > packet_data + packet_size)
                {
                    goto done;
                }
            }
        }
        else if (type_map[i] == 0x0C)
        {
            if (arg)
            {
                *arg = 0;
            }
        }
        else if (type_map[i] == 0x0D)
        {
            va_arg(args, u32*);
        }
    }
    ret = 1;

done:
    va_end(args);
    return ret;
}

函数参数在C中非常清楚,今天早些时候我试图在C#中创建这个函数。

但由于C#unsafe代码的某些限制,我无法完全完成它。

我被困在最后一个参数,这是可变数量的参数。我不知道怎么写这个。

当您将某些内容传递给va_list时,需要一堆指向未知类型数据的指针,如下所示:

byte        action          = 0xFF;
byte        *npc_block      = 0;
u32         character_id;
u32         skill_id;
u32         skill_tid;
byte        arg_5;
byte        arg_6;
byte        arg_7;
u32         npc_tid;
u32         npc_function;
Npc         *npc;

parseClientPacket(p->data, p->size, 1, 1, 8, type_map, size_map,
        &action,
        &npc_block,
        &character_id,
        &skill_id,
        &skill_tid,
        &arg_5,
        &arg_6,
        &arg_7)

我尝试使用params object[]替换可变数量的参数,但是byte*似乎不能转换为object

谢谢!

0 个答案:

没有答案