【genius_platform软件平台开发】第十二点:最终结案:字节对齐未恢复引起的数据成员赋值和析构异常的问题

今早在调试我64的sdk时发现,如果形参sz=16的时候(默认值),但是在构造函数中对数据成员进行赋值出现 count=0; size=sz; 结果却是cout=16,size =0特别奇怪;

代码如图:

GpSocketDef.h文件


//
//
class ParamHostAddr
{
public:
    struct tagADDR
    {
        INT32 type;
        char ip[GP_MAX_IP];
        char mac[INTER_MAX_MAC];
    };

    ParamHostAddr(INT32 sz = 16)
    {
        addrs = NULL;
        count = 0;
        size = sz;
        memset(hostname, 0, sizeof(hostname));
        addrs = (tagADDR*)malloc(sizeof(tagADDR) * size);
        memset(addrs, 0, sizeof(tagADDR) * size);
    }

...

    char hostname[MAX_PATH];
    tagADDR* addrs;
    INT32 count;
    INT32 size;
};

 

GpSysNetwork.h头文件

进行前置声明和在GpSysNetwork.cpp中进行调用

GpSysNetwork.cpp文件


//
//
INT32 getHostAddrInfo(ParamHostAddr& addr)
{
#if defined(WIN32) || defined(WIN64)
    //*** 初始化网络库,否则gethostname获取失败10093错误
    if (!g_bWSAStartup)
    {
        if (ReturnCode_Error == loadNetModule())
        {
            return ERR_SOCK_ERROR;
        }
    }

    INT32 ret = gethostname(addr.hostname, sizeof(addr.hostname));
    if (SOCKET_ERROR == ret)
    {
        // windows和linux系统获取错误码的接口有差异
        INT32 err = getLaseError();
        return ERR_SOCK_ERROR;
    }
    //printf("host name is %s \n", addr.hostname);
    addrinfo hints, * results = NULL;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    ret = ::getaddrinfo(addr.hostname, NULL, &hints, &results);
    if (NULL == results)
    {
        return ERR_SOCK_ERROR;
    }
    if (ret != 0)
    {
        //m_nErrorCode = ret;
        //OnError(ret);
        freeaddrinfo(results);
        return ERR_SOCK_ERROR;
    }
    for (addrinfo* ptr = results; ptr != NULL && addr.idle(); ptr = ptr->ai_next)
    {
        sockaddr_in* pin = (sockaddr_in*)ptr->ai_addr;
        addr.addr().type = pin->sin_family;
        strcpy(addr.addr().ip, inet_ntoa(pin->sin_addr));
        addr.add();
    }
    //freeaddrinfo
    freeaddrinfo(results);
#elif defined(__linux__)
    // linux系统getaddrinfo获取所有ip的功能异常,改用getifaddrs
    ifaddrs *ifaddr,*ifaddrHeader;
    if (getifaddrs(&ifaddr) != 0)
    {
        perror("getifaddrs :");
        return ERR_SOCK_ERROR;
    }
    ifaddrHeader = ifaddr;

    for (; ifaddr != NULL; ifaddr = (*ifaddr).ifa_next)
    {
        if ((*ifaddr).ifa_addr != NULL)
        {
            int family = ifaddr->ifa_addr->sa_family;
            if (family == AF_INET)
            {
                addr.addr().type = family;
                // linux需要添加广播地址而不是ip地址
                inet_ntop(AF_INET, &((((sockaddr_in*)((*ifaddr).ifa_addr))->sin_addr)), addr.addr().ip, GP_MAX_IP);
                //inet_ntop(AF_INET, &((((sockaddr_in*)(*ifaddr).ifa_broadaddr)->sin_addr)), addr.addr().ip, GP_MAX_IP);
                addr.add();
            }
        }
    }
#endif
    return ERR_SUCCESS;
}

在CGpNetUdpBroadcast.cpp中进行调用


//
//
void CGpNetUdpBroadcast::appendBroadcastClients(int nProtType)
{
    ParamHostAddr haddr;        // 这里进行调用
    getHostAddrInfo(haddr);                
    for (INT32 i = 0; i < haddr.count; ++i)
    {
        ULONG uip = ipToLong(haddr.addrs[i].ip);
        if (this->isExsit(uip))
        {
            //LOGWARNING("CGpNetUdpBroadcast::appendBroadcastClients isExsit ip=[%s]", haddr.addrs[i].ip);
            continue;
        }
        CGpUdpSocketClient* pClient = new CGpUdpSocketClient((SockModeType)nProtType);
        if (!pClient)
        {
            LOGERROR("CGpNetUdpBroadcast::appendBroadcastClients pClient is NULL ip=[%s] nProtType=[%d]", haddr.addrs[i].ip, nProtType);
            continue;
        }

        ...
}

初步解决方案

居然是移动一下成员变量:(原因未详)

终极解决方案

字节对齐引发的一场血案!!!

晚上进行了一波头文件包含的精简操作,发现CGpFramePacketAssembly.hCGpFrameBaseProcess.h头文件一定要包含一个无关的头文件#include "Base/NetBase/GpNetBase.h"当时觉得就很奇怪,引起了特别的注意,为什么无关却还是必须要包含那。当时进行了屏蔽发现只要屏蔽就会出现析构异常崩溃的问题,于是把这个头文件包含的其他头文件进行分类屏蔽。

定位到一定要包含这个IGpNetBase.h这个头文件

继续屏蔽排查,发现一定要包含GpMsgAll.h这个头文件

愈发奇怪,怎么会和数据包的头文件相关那?没道理啊,不解,继续二分法屏蔽排查。

最终发现一定要包含#include "IpToolsMsg/GpMsgIpToolsOperateDevice.h"头文件,该头文件是我们做网络设置模块相关的时候加入的,当时加入后就出现了一些析构异常的问题,一直以为是前置声明的关系引发的。最终在这个文件中发现了字节对齐,引起特别注意,发现没有恢复字节对齐。最终进行恢复测试下来发现不管是win32位还是64位都好了。终于结案了!!!小伙伴们可以安心开发功能了

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隨意的風

如果你觉得有帮助,期待你的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值