2013-03-07 116 views
1

我有一个从(DLL)调用的回调函数(在C++ exe应用程序中定义)。 Declaraction在DLL(C++ Builder的2009年):在回调函数中传递数据

typedef struct{ 
INT32  time_stamp;  
INT32  id;    
INT8  len:4;   
INT8  rtr:1;  
INT8  res:3;   
INT8  a_data[8];  
INT8  sts;    
} COTI_CAN_OBJ; 

typedef void (__closure __fastcall *COTI_t_UsrRxIntHdlr)(UINT16 count, COTI_CAN_OBJ far * p_obj); 

当我在DLL调用这个回调是执行好,但在p_obj传递的值是不正确的,它看起来是从比通过不同势的地方(地址)拍摄。

任何人都可以帮忙吗?

这是由C++程序(主机)在我的DLL(客户端)调用的函数和作为参数的指针回调函数传递:

COTI_t_UsrRxIntHdlr local_int_hdlr; 
COTI_CAN_OBJ obj; 

extern "C" __declspec(dllexport) __cdecl UINT32 COTI_InitBoard(
    UINT16 board_seg, 
    COTI_t_UsrRxIntHdlr fp_int_hdlr, 
    COTI_t_UsrExcHdlr fp_exc_hdlr 
    ) 
    { 
    local_int_hdlr = fp_int_hdlr; 
    local_exc_hdlr = fp_exc_hdlr; 

    fp_int_hdlr(0,NULL); 

    return 1; 
    } 

然后在另一个函数I调用回调作为:

... 
    obj.id=0x701; 
    obj.len=5; 
    obj.a_data[0]=10; 
    obj.a_data[1]=20; 
    obj.a_data[2]=30; 
    obj.a_data[3]=40; 
    obj.a_data[4]=50; 
local_int_hdlr(1, &obj); 
    ... 

这是在C回调函数的声明++应用程式(主机):

static void CotiRxHandler(UINT16 count, COTI_CAN_OBJ *p_obj) 
{ 
    ... 
    return; 
} 
+2

你将不得不显示一些真正的代码恐怕 – 2013-03-07 12:09:00

回答

0

我认为与调用约定有关。你确定用__fastcall调用它,因为默认的调用约定是windows的__stdcall。

编辑:

可能有数据对齐问题。尝试解决方案如下:

添加

#pragma pack(push,1) //Add 

typedef struct{ 
INT32  time_stamp;  
INT32  id;    
INT8  len:4;   
INT8  rtr:1;  
INT8  res:3;   
INT8  a_data[8];  
INT8  sts;    
} COTI_CAN_OBJ; 

#pragma pack(pop) //Add 

你struct声明。

更新2:

变化:

静态无效CotiRxHandler(UINT16计数,COTI_CAN_OBJ * p_obj)

静态无效__ FASTCALL CotiRxHandler(UINT16计数,COTI_CAN_OBJ * p_obj)

+0

如果我改变任何调用转向,然后c + +应用程序挂起。 只有这样的调用这个回调工作,但通过paarameters不是我通过。我认为这是因为: COTI_CAN_OBJ far * p_obj因为在C++应用程序中,我只能看到在p_obj结构中传递的数据,但是这个传递的结构中的数据并不是我设置的。我认为问题是关于指针地址的声明,但我不知道是什么。 – Jacek 2013-03-08 11:03:10

+0

@Jaek:提供来电显示。 – CasperGhost 2013-03-09 04:52:40

+0

我添加了: #pragma pack(push,1)//添加 #pragma pack(pop)//添加 但它没有帮助。 – Jacek 2013-03-10 10:33:35

0

除了什么@CasperGhost建议,我会建议你调试代码 - 尤其是周围的DLL/EXE边界。查看调用函数时传递的内容(即局部变量的内容为COTI_CAN_OBJ)。现在,仔细查看被调用函数中相同变量的内容 - 查看是否所有内容都匹配。你应该在数据类型上使用sizeof(即COTI_CAN_OBJ)来查看它在DLL和EXE(或DLL)中是否相同。