我正在寻找关于是否可以将此功能从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
。
谢谢!