1

我有一个从 (DLL) 调用的回调函数(在 c++ exe 应用程序中定义)。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 中传递的值不正确,它看起来是从不同的位置(地址)获取而不是传递。

有人可以帮忙吗?

这是由我的 dll(客户端)中的 c++ 应用程序(主机)调用的函数,并作为参数传递回调函数的指针:

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;
    }

然后在另一个函数中,我将回调称为:

...
     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;
}
4

2 回答 2

0

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

编辑:

可能存在数据对齐问题。尝试下面给出的解决方案:

添加

#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

到你的结构声明。

更新 2:

改变:

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

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

于 2013-03-07T16:38:29.883 回答
0

除了@CasperGhost 推荐的内容之外,我还建议您调试代码——尤其是在 DLL/EXE 边界附近。查看调用函数时传递的内容(即局部变量的内容COTI_CAN_OBJ)。现在,仔细查看被调用函数中相同变量的内容——看看是否一切都匹配。您应该使用sizeof数据类型(即COTI_CAN_OBJ)来查看它在 DLL 和 EXE(或 DLL)中是否相同。

于 2013-03-10T12:54:30.593 回答