gpt4 book ai didi

c++ - 我们可以在将对象转换为 (char *) 后取回对象吗

转载 作者:行者123 更新时间:2023-11-28 06:21:48 25 4
gpt4 key购买 nike

        msg->msgType = JOINREPLY;
memcpy((char *)(msg+1), &memberNode->addr.addr, sizeof(memberNode->addr.addr));
memcpy((char *)(msg+1) + 1 + sizeof(memberNode->addr.addr), &memberNode->memberList, sizeof(memberNode->memberList));

这是我想通过调用另一个函数从一个函数发送的消息,该函数是 send((char *)msg, msgsize);

msg的数据结构是

enum MsgTypes{
JOINREQ,
JOINREPLY,
DUMMYLASTMSGTYPE,
HEARTBEAT
};

typedef struct MessageHdr {
enum MsgTypes msgType;
}MessageHdr;

vector<MemberListEntry> memberList;是memberList的定义,可以看到memberList是一个MemberListEntry类型的vector,MemberListEntry有自己的数据。

int id;
short port;
long heartbeat;
long timestamp;

由于我正在将完整的 memberList 转换为 (char *),是否可以再次将 (char *) 转换为 memberList 或 MemberListEntry 类型并对其进行迭代?

        MemberListEntry *ml;
ml=(MemberListEntry *)malloc(sizeof(MemberListEntry));
for(char *j=finalData; i < (int)string(finalData).length(); j = (char *)(j+ sizeof(MemberListEntry))){
ml= (MemberListEntry *)j;
i+=sizeof(MemberListEntry);


idR=ml->getid();
portR=ml->getport();
heartbeatR=ml->getheartbeat();
//Do some stuff
}

“finalData”是我在删除 msgType 和我存储的地址后得到的数据,将我的指针指向我以 char 格式存储我的 memberList 的位置。

最佳答案

您需要在邮件 header 中包含一个字段,指示邮件包的整体大小。

可能是这样的:

typedef struct MessageHdr {
enum MsgTypes msgType;
unsigned int msgLength;
} MessageHdr;

存储在 msgLength 字段中的实际值取决于约定,例如它可以不同于整个消息包的大小或减去 header 的大小,或者只是 MemberListEntry 的计数。使用您喜欢的任何东西。

您使用 send((char *)msg, msgsize); 通过 tcp 套接字发送。但是,您的对等方无法找出重要的 msgsize 值来重建消息数据,除非您明确地将其作为消息 header 的一部分发送。

那么重建它们应该是微不足道的。

首先你应该弄清楚你的消息包中有多少条目。然后你分配一个那个大小的新 vector 。最后你 memcpy 所有数据到新 vector 中,一切都应该没问题。


原则 1:您无法从任何地方获取信息。

sizeof 起作用是因为编译器知道大小。 它们是根据规范、平台或您#included 的头文件预定义的。它们是固定的。而且它们永远不会改变。

.length() 之所以有效,是因为 std::vector 在场景下为您保留了长度信息。 您可以检查他们的自己对应头文件。

简而言之,它们都不是来自于自动找出任意内存区域中包含的内容的奇特魔法。

在您的情况下,信息 - “实际元素计数” - 是至关重要的。并且它必须可供对等方访问以重建数据结构。

原则 #2:其中包含指针的数据结构不能直接通过网络发送。

指针只在当前进程中有效。您不能盲目地通过网络发送指针。所以发送你聪明的 std::vector 也不起作用。尽管 std::vector 本身具有固定大小并且您可以对其应用 sizeof,但它在内部使用指针来保存可以动态更改的实际数据。


好吧,您真正需要的是某种数据编码/对象序列化。您需要将数据转换为适合网络传输的某种表示形式,然后再将它们转换回来。在 C++ 领域,你必须自己做。没有魔法。

如果您觉得实现这样的事情真的很无聊,请考虑使用一些高级语言来为您处理对象序列化。例如,Javascript 原生支持著名的 JSON 格式,这种格式在数据交换方面非常出色。或者您可以使用 C#,它具有快速高效的强类型二进制序列化程序。

关于c++ - 我们可以在将对象转换为 (char *) 后取回对象吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29190820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com