lib for realteimMM funcs
callbacknotes.cpp@5:3906f93b8b39, 2018-02-16 (annotated)
- Committer:
- GTNicholson
- Date:
- Fri Feb 16 10:03:35 2018 +0000
- Revision:
- 5:3906f93b8b39
- Parent:
- 3:13301255d95a
Changing Pin assignment
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
GTNicholson | 3:13301255d95a | 1 | /* |
GTNicholson | 3:13301255d95a | 2 | |
GTNicholson | 3:13301255d95a | 3 | Because a member function is meaningless without an object to invoke it on, you can’t do this directly (if The X Window System was rewritten in C++, it would probably pass references to objects around, not just pointers to functions; naturally the objects would embody the required function and probably a whole lot more). |
GTNicholson | 3:13301255d95a | 4 | |
GTNicholson | 3:13301255d95a | 5 | As a patch for existing software, use a top-level (non-member) function as a wrapper which takes an object obtained through some other technique. Depending on the routine you’re calling, this “other technique” might be trivial or might require a little work on your part. The system call that starts a thread, for example, might require you to pass a function pointer along with a void*, so you can pass the object pointer in the void*. Many real-time operating systems do something similar for the function that starts a new task. Worst case you could store the object pointer in a global variable; this might be required for Unix signal handlers (but globals are, in general, undesired). In any case, the top-level function would call the desired member function on the object. |
GTNicholson | 3:13301255d95a | 6 | |
GTNicholson | 3:13301255d95a | 7 | Here’s an example of the worst case (using a global). Suppose you want to call Fred::memberFn() on interrupt: |
GTNicholson | 3:13301255d95a | 8 | |
GTNicholson | 3:13301255d95a | 9 | class Fred { |
GTNicholson | 3:13301255d95a | 10 | public: |
GTNicholson | 3:13301255d95a | 11 | void memberFn(); |
GTNicholson | 3:13301255d95a | 12 | static void staticMemberFn(); // A static member function can usually handle it |
GTNicholson | 3:13301255d95a | 13 | // ... |
GTNicholson | 3:13301255d95a | 14 | }; |
GTNicholson | 3:13301255d95a | 15 | // Wrapper function uses a global to remember the object: |
GTNicholson | 3:13301255d95a | 16 | Fred* object_which_will_handle_signal; |
GTNicholson | 3:13301255d95a | 17 | void Fred_memberFn_wrapper() |
GTNicholson | 3:13301255d95a | 18 | { |
GTNicholson | 3:13301255d95a | 19 | object_which_will_handle_signal->memberFn(); |
GTNicholson | 3:13301255d95a | 20 | } |
GTNicholson | 3:13301255d95a | 21 | int main() |
GTNicholson | 3:13301255d95a | 22 | { |
GTNicholson | 3:13301255d95a | 23 | signal(SIGINT, Fred::memberFn); // Can NOT do this |
GTNicholson | 3:13301255d95a | 24 | signal(SIGINT, Fred_memberFn_wrapper); // Okay |
GTNicholson | 3:13301255d95a | 25 | signal(SIGINT, Fred::staticMemberFn); // Okay usually; see below |
GTNicholson | 3:13301255d95a | 26 | } |
GTNicholson | 3:13301255d95a | 27 | Note: static member functions do not require an actual object to be invoked, so pointers-to-static-member-functions are usually type-compatible with regular pointers-to-functions. However, although it probably works on most compilers, it actually would have to be an extern "C" non-member function to be correct, since “C linkage” doesn’t only cover things like name mangling, but also calling conventions, which might be different between C and C++. |
GTNicholson | 3:13301255d95a | 28 | |
GTNicholson | 3:13301255d95a | 29 | Test |
GTNicholson | 3:13301255d95a | 30 | */ |