C++ 将指针作为参数传递给从属dll对象的大小错误

C++ 将指针作为参数传递给从属dll对象的大小错误,c++,c,visual-studio-2010,visual-c++,master-slave,C++,C,Visual Studio 2010,Visual C++,Master Slave,我有两个模块。一个调用另一个并将结构作为参数传递 struct { char* szDGRTag; bool bTagEx; } ADPTAG; 主在C++中用“C++ 98”编写。从属是用C++ 11在Visual Studio 2010中编写的专业。 在从属中调用的函数: long lCheckPresenceOfFields (char* szName, ADPTAG* AdpTagList, long lNbVar) 总的来说: long lNbVar = 2; AD

我有两个模块。一个调用另一个并将结构作为参数传递

struct {
    char* szDGRTag;
    bool bTagEx;
} ADPTAG;

主在C++中用“C++ 98”编写。从属是用C++ 11在Visual Studio 2010中编写的专业。 在从属中调用的函数:

long lCheckPresenceOfFields (char* szName, ADPTAG* AdpTagList, long lNbVar)
总的来说:

long lNbVar = 2;
ADPTAG* AdpTagList = NULL;
AdpTagList = new ADPTAG[lNbVar];

AdpTagList[0].szTag = new char[32];
AdpTagList[0].bTagEx = true;
memset(AdpTagList[0].szTag, 0x0, 32+1);
AdpTagList[0].szTag = NULL;

AdpTagList[1].szTag = new char[32]; 
AdpTagList[1].bTagEx = true;
memset(AdpTagList[1].szTag, 0x0, 32+1);
AdpTagList[1].szTag = NULL;

int size = sizeof(AdpTagList[0]);
AdpTagList[0].szTag = "DDD";
AdpTagList[1].szTag = "AAA";

long pres = pGetFieldsPresence(szPath, AdpTagList, 2);
我已经检查了主设备中AdpTagList[0]的大小,它是5个字节,但从设备中是8个字节,所以第一个对象是可以的,但下一个对象是坏的,因为指针指向错误的内存区域。
这里有什么问题?不同的编译器?可能不是因为只有char*和int的结构在这两个模块之间工作良好。

考虑到第一个对象[0]的大小,第二个对象[1]是空指针。

是的,这是编译器的差异造成的。在二进制级别,C++没有标准化。特别是,这意味着任何编译器都可以自由地为结构选择自己的填充规则,这正是影响您的地方。显然,较新的编译器决定添加3字节的填充以使结构64位对齐,但较旧的编译器没有这样做


一般来说,无法确保两个不同编译器生成的数据之间的二进制兼容性。您可以切换到使用字节流,也可以对两者使用相同的编译器。

您遇到了打包差异。您可以使用修改包装

默认情况下,由于Visual Studio:

在8字节边界上打包结构

Visual Studio 2010编译器很可能没有指定打包。您的Visual C++ 6应用程序可能指定了1字节填充作为包含<代码> int <代码>的结构,而char >应该打包进去。

使用1字节打包优化程序系统内存占用,因为填充不会丢失内存

使用8字节打包可以优化速度,因为它增加了在单个加载中获取结构的机会

有关包装的更多信息,请阅读:

但我同意微软的说法:

除非有特定的对齐要求,否则不应使用此选项


意思是,因为你必须改变一个,我建议在Visual C++ 6应用程序上更改包装。< /P>可能的副本,这会有什么帮助?两个模块中bool的大小均为1,两个模块中char*的大小均为4。vc6中的对象大小是5,vs2010中的对象大小是8,那么它必须是在.h文件中定义的不同填充。我不使用任何填充,所以我相信它是默认值。如何检查/修复此问题?顺便说一句,完全不是重复的。从属模块将与许多主模块一起使用。所以我假设最好的选择是使用char*和int,编译为8字节,没有填充。它将兼容1、2、4或8 byt结构成员对齐的主控形状。然而,可能不是16岁,但我可以假设,不会有这样的情况。你怎么看?@我已经编辑过MrkkcZaPrimi,但是我的首选是在Visual C++ 6中修复对齐。如果您担心内存占用,您可以购买更多的ram。你永远买不到更多的时间。是的,但这对我来说意味着每个其他主模块都必须检查这个填充。好的,我现在明白了。你是对的。在这种情况下,我可能会坚持使用整数的布尔形式。在每个主模块中,将Struct Align设置为8字节作为MS标准。虽然答案是有意义的,并且在本例中似乎是正确的,但我不得不指出,即使在VC++6中,默认的打包也是8字节。因此,必须有人将该设置更改为1字节。这是一个糟糕的决定,正确对齐的值的速度提升远远超过了至少386处理器以来节省的空间。如果你在内存中构建巨大的对象阵列,可能会有更大的不同,但这是“医生,我这么做的时候很痛”…“那就停止做吧”之类的事情之一。