2012-06-12 27 views
0

我无法追查的奇怪行为的原因在传递一个结构作为参数。结构参数损坏的函数调用

在的问题,structFoo的结构,具有以下声明:

typedef struct _structFoo { 
    int id; 
    BSTR szDescription; 
    VARIANT vData; 
    BOOL bTransient; 
} structFoo; 

我有两个模块,A和B模块A呼叫B :: foo的(中间体ID,UINT滤波器,structFoo SF)。在A中,在调用之前,structFoo结构正确地形成并填充有效数据。但是,一旦函数调用B :: foo(),structFoo参数就会有垃圾数据。经进一步检查,原来是复制结构的地址放入id字段,以及szDescription指向最近使用的字符串。函数调用后其他参数是正确的。

我不知道这种错位的原因,还是不管发生,但在我看来,直到函数调用时,一切都在适当的位置。下面是导致该函数调用拆卸:

0000000006003211 lea   rdi,[rsp+230h] 
0000000006003219 lea   rsi,[sAttPairId] 
0000000006003221 mov   ecx,30h 
0000000006003226 rep movs byte ptr [rdi],byte ptr [rsi] 
0000000006003228 mov   rax,qword ptr [piConstruct] 
0000000006003230 mov   rax,qword ptr [rax] 
0000000006003233 lea   r9,[rsp+230h] 
000000000600323B mov   r8d,800h 
0000000006003241 mov   edx,dword ptr [iHighNodeId] 
0000000006003248 mov   rcx,qword ptr [piConstruct] 
0000000006003250 call  qword ptr [rax+60h] 

这里是函数调用后拆卸:

0000000004B72470 mov   qword ptr [rsp+20h],r9 
0000000004B72475 mov   dword ptr [rsp+18h],r8d 
0000000004B7247A mov   dword ptr [rsp+10h],edx 
0000000004B7247E mov   qword ptr [rsp+8],rcx 
0000000004B72483 push  rsi 
0000000004B72484 push  rdi 
0000000004B72485 sub   rsp,0A8h 
0000000004B7248C mov   rdi,rsp 
0000000004B7248F mov   rcx,2Ah 
0000000004B72499 mov   eax,0CCCCCCCCh 
0000000004B7249E rep stos dword ptr [rdi] 
0000000004B724A0 mov   rcx,qword ptr [rsp+0C0h] 
0000000004B724A8 mov   qword ptr [rsp+90h],0FFFFFFFFFFFFFFFEh 

sub rsp, 0A8h的参数都设定数据后,但顺丰参数有它的id字段中正确的structFoo信息的地址,而不是将此地址用作其自己的指针。有关解决此问题的任何指导都非常感谢。不幸的是,改变B :: foo()以获取结构的地址而不是结构本身不是一种选择。大量的遗留代码依赖于这个功能,我没有权力去改变。

谢谢!

+0

您可以显示'B :: foo的(INT ID,UINT过滤器,structFoo SF)'的代码? – andre

+0

这可能是一个愚蠢的问题,但。你为什么要'typedef struct'? – andre

+1

有**不需要**在C++中声明结构为'typedef struct TAG_NAME {} REAL_NAME;''。只要做'struct REAL_NAME {};' –

回答

0

我想,模块AB与不同的调用约定编译。模块A通过引用/指针将结构传递给函数,而模块B预计按值接收堆栈上的结构。

有可能在B的头文件中的修改,就像这样:

__weird_call void B::foo(int id, uint filter, structFoo sF); 

也许模块A的编译器不理解,或者一些其他的头文件定义了它(#define __weird_call /* nothing */) ,或者沿着这些线路。

0

我偶然发现了这个页面,同时寻找我遇到的类似问题的答案。 虽然我不能在互联网上找到答案,共享调试的经验。

的下面结构通过参考从一个函数传递到其他,接收器将发现所接收的数据是出乎意料的:

typedef struct 
{ 
    char time_st[30]; 
    char pipe_no; 
    float loss; 
    float power[4]; 
    int mode; 
    int count; 
}Parameters; 

另一个发现是,如果我在同一文件中定义接收器功能作为来电功能,问题会消失。

经过调试,发现根本原因是意大利面使用遗留的“#pragma pack”。h文件导致结构打包的问题 - 由于在调用函数的.c文件中包含了几个遗留的头文件,所以结构被打包,但是在接收函数的.c文件中(这是写入新的在项目活动期间),结构被视为未包装。

分辨率:增加足够的留白,使结构字对齐

typedef struct 
{ 
    char time_st[30]; 
    char pad; 
    char pipe_no; 
    float loss; 
    float power[4]; 
    int mode; 
    int count; 
}Parameters;