Studio:Working with pointers to target-resident functions: Difference between revisions
(Controlling target-resident callbacks) |
|||
Line 1: | Line 1: | ||
=== | === A technique for controlling target-resident callbacks from a target function. === | ||
Occasionally it is desirable to execute functions on target that are unknown to the host, that is, the functions to be called are implemented on the target and not exposed to the host through an interface. | Occasionally it is desirable to execute functions on target that are unknown to the host, that is, the functions to be called are implemented on the target and not exposed to the host through an interface. |
Revision as of 20:44, 13 July 2007
A technique for controlling target-resident callbacks from a target function.
Occasionally it is desirable to execute functions on target that are unknown to the host, that is, the functions to be called are implemented on the target and not exposed to the host through an interface. For example, a target-based function, TaskCreate could accept as input a function pointer that it uses to start a task. These task functions are unknown to the caller of TaskCreate on the host. The pointer passed into TaskCreate is opaque from the caller's perspective. As far as the caller knows, he gets a task handle from somewhere, and calls TaskCreate to start it.
So, how can a task handle be obtained by the host? A target-based inline helper function could be written to pass back an opaque pointer to an appropriate function, based on some criteria passed in by the caller.
We'll use the following code sample to illustrate our example:
typedef enum { TASK_SETUP, TASK_READ, TASK_SHUTDOWN } ETaskTypes; typedef void (*TaskHandle)(void); void TaskCreate(TaskHandle handle); void Setup(void); void Read(void); void Shutdown(void); __inline void* getTaskHandle(ETaskTypes eChoice) { switch (eChoice) { case TASK_SETUP: return &Setup; case TASK_READ: return &Read; case TASK_SHUTDOWN: return &Shutdown; default: return 0; } } #pragma scl_function(getTaskHandle) #pragma scl_function(TaskCreate)
Here, TaskCreate is our captured function on the target that accepts task handles to start. getTaskHandle is our helper function that takes a choice as input and returns a pointer to one of the internal functions Setup, Read, and Shutdown. The only interfaces to the host are the captured functions getTaskHandle and TaskCreate.
Finally, we show how these interfaces are called from a host script:
studio.Workspace.Interfaces.Item("getTaskHandle").Owner.Register(); studio.Workspace.Interfaces.Item("TaskCreate").Owner.Register(); var fnGetTaskHandle = ascript.Functions.Item("getTaskHandle"); var fnTaskCreate = ascript.Functions.Item("TaskCreate"); // get and call the setup task fnGetTaskHandle.User.ParameterList.eChoice = 0; fnGetTaskHandle.User.Call(); ascript.MessageBox(fnGetTaskHandle.User.ReturnValue); fnTaskCreate.User.ParameterList.handle = fnGetTaskHandle.User.ReturnValue; fnTaskCreate.User.Call(); // get and call the read task fnGetTaskHandle.User.ParameterList.eChoice = 1; fnGetTaskHandle.User.Call(); ascript.MessageBox(fnGetTaskHandle.User.ReturnValue); fnTaskCreate.User.ParameterList.handle = fnGetTaskHandle.User.ReturnValue; fnTaskCreate.User.Call(); // get and call the shutdown task fnGetTaskHandle.User.ParameterList.eChoice = 2; fnGetTaskHandle.User.Call(); ascript.MessageBox(fnGetTaskHandle.User.ReturnValue); fnTaskCreate.User.ParameterList.handle = fnGetTaskHandle.User.ReturnValue; fnTaskCreate.User.Call();