这是一个可以注册成回调的函数,注册事件发生时会调用它。通过提供与以下 typeDef 相匹配的函数指针注册此函数:
type CciRegCallbackStatus(在 BipCci.h 中定义)
对于这五个实用程序函数中的每个实用程序函数,CciObject 参数必须为 NULL。
声明以下 struct 和函数:
typedef struct { int id; }MyContext; static int registered=0; CciRegCallbackStatus switchThreadStateChange(CciDataContext *context, CciCallbackType type) { char traceText[256]; char* typeStr=0; MyContext* myContext = (MyContext*)context; if (type==CCI_THREAD_STATE_IDLE){ typeStr = "idle"; }else if(type==CCI_THREAD_STATE_INSTANCE_END){ typeStr = "instance end"; }else if (type==CCI_THREAD_STATE_TERMINATION){ typeStr = "termination"; }else{ typeStr = "unknown"; } memset(traceText,0,256); sprintf(traceText,"switchThreadStateChange: context id = %d, thread state %s",myContext->id,typeStr); cciServiceTrace(NULL, NULL, traceText); return CCI_THREAD_STATE_REGISTRATION_RETAIN; }
将以下代码放入样本中的 _Switch_evaluate 函数,使您能够阅读服务跟踪并查看何时消息处理线程更改状态:
/*register for thread state change*/ CciMessageContext* messageContext = cniGetMessageContext(NULL,message); CciThreadContext* threadContext = cniGetThreadContext(NULL,messageContext); static MyContext myContext={1}; if(registered==0){ cciRegisterForThreadStateChange( NULL, threadContext, & myContext, switchThreadStateChange, CCI_THREAD_STATE_IDLE | CCI_THREAD_STATE_INSTANCE_END | CCI_THREAD_STATE_TERMINATION); registered=1; }
此示例仅在接收消息的第一个线程上进行注册。如果需要注册每个接收消息的线程,则用户定义的扩展必须记住它们注册所在的线程。
使用 userContext 参数,您可以查看数据是如何从注册回调的代码传递到实际的回调函数。
当注册回调时,传入指向 MyContext struct 的实例的指针。该指针与传回回调的指针相同。要确保该指针在传递到回调时仍然有效,将 struct 的实例声明为静态。另一个确保指针有效的技术是在堆上分配存储。
在回调函数中,可以将 userContext 参数类型强制转换成 (MyContext*)。可以通过此地址引用原始的 MyContext struct。这允许数据从注册回调的代码传递到该回调函数。