![]() |
Telelogic DOORS (steve huntington) | ![]() |
new topic :
profile :
search :
help :
dashboard :
calendar :
home
|
||
Latest News:
|
|
Topic Title: can't use function pointer retrieved from Array Topic Summary: Created On: 11-Sep-2003 00:46 Status: Post and Reply |
Linear : Threading : Single : Branch |
![]() |
![]()
|
![]() |
|
hi all,
this is a message I just sent to the telelogic support department, and it occured to me that I might also see if someone on this forum has an idea of how to solve the problem. any experience would definitely be helpful, as would a general idea of how others have managed the complexity of a non-trivial DB GUI. thanks in advance for your advice, Kip Kohn Independent Software Contractor, Mahi Networks kkohn@mahinetworks.com I'm using DOORS 5.2. I've successfully passed function pointers to functions, and invoked them within, but what I need to do here is create a dispatch-table-like structure for managing a very complex GUI. I want to store function pointers in an Array, and then invoke them at the appropriate time. I have tried every combination of pointer, and reference syntax I could think of, and nothing is working. below is my code, followed by the notes I took on what happened in 12 different combinations of type declaration X function pointer invocation syntax. The one I originally believed should work is 1.c., which I've repeated below: string str = get(a, i, 0); void (*func)(string) = get(a, i, 1); func(str); alas, it did not actually invoke my function pointer func. All casts I tried to put on the get() call caused syntax errors, although I don't think this is a problem of mistyping. rather, the invocation of func is simply not happening. Anyway, please let me know how I can solve this problem. I am not necessarily attached to the Array data structure. I would be perfectly happy if you could show me how to store a function pointer in a regular [] array or a skip list--just so long as I could retrieve it later and invoke what it points to. The bottom line, is that I need this facility. As you know, DXL has neither closures nor objects, and it is intensely difficult to handle the complexity of this project's GUI, which contains 2 windows, one having 5 tabs, and encapsulates 6 modules. I'm trying desperately to build a state table, where pre-registered callbacks can be invoked on a set of DBEs when the GUI enters a predefined state. I shudder to think of having to write and maintain my own work-around via a symbolic reference hack: void call_func_by_name(string name, DBE elem) { if (name == "foo") foo(elem); else if (name == "bar") bar(elem); else if (name == "baz") baz(elem); else error "unknown function; consider adding a condition to call_func_by_name()\n"; } ugly!!! see what I mean? if you can't help me find a way to store a function pointer, please at least tell me how you would use--or better have used--DXL to manage state changes in a window with over 100 DBEs. It's possible I'm just approaching this problem in the wrong way. What I'm trying to stay away from however is the following, which is nearly impossible to understand and maintain: if (state == 1) { // 100 hide invocations // 10 show invocations } else if (state == 2) { // 100 hide invocations // 8 show invocations } thanks in advance for all of your assistance, Kip Kohn kkohn@mahinetworks.com code follows, followed by notes: ========================================================== void foo(string s) { print "getting ready to foo with " s "\n"; } void bar(string s) { print "getting ready to bar with " s "\n"; } void baz(string s) { print "getting ready to baz with " s "\n"; } Array a = create(3, 2); put(a, "funny", 0, 0); put(a, foo, 0, 1); put(a, "funky", 1, 0); put(a, bar, 1, 1); put(a, "flava", 2, 0); put(a, baz, 2, 1); void call_my_fp(void fp(string), string s) { fp(s); } int i; for (i = 0; i < 3; i++) { string str = get(a, i, 0); void (&func)(string) = get(a, i, 1); print "calling the func on '" str "'\n"; // func(str); // call_my_fp(func, str); // (*func)(str); // (&func)(str); } ========================================================== /* NOTES: syntactically legal to write all three: a. void (&func)(string) = get(a, i, 1); b. void (func)(string) = get(a, i, 1); c. void (*func)(string) = get(a, i, 1); 1. when I later execute: func(str); a. -E- DXL: <Line:43> incorrectly concatenated tokens -I- DXL: <Line:92> all done with 1 error and 0 warnings b. message box appears: title: DOORS report; message: Internal error, please submit a problem report c. program runs, but doesn't give output printed inside the functions: calling the func on 'funny' calling the func on 'funky' calling the func on 'flava' 2. when I later execute: call_my_fp(func, str); a. CRASH: The instruction at "0x00598bfa" referenced memory at "0x636e7566". The memory could not be "read". Click on OK to terminate the program Click on CANCEL to debug the program (initiates Visual C++) b. -R-E- DXL: <Line:44> forward reference not resolved c. -E- DXL: <Line:44> incorrect arguments for function (call_my_fp) -I- DXL: <Line:80> all done with 1 error and 0 warnings 3. when I later execute: (*func)(str); a. -E- DXL: <Line:45> incorrect argument for ((*)) -E- DXL: <Line:45> incorrectly concatenated tokens -I- DXL: <Line:100> all done with 2 errors and 0 warnings b. -E- DXL: <Line:45> incorrect argument for ((*)) -E- DXL: <Line:45> incorrectly concatenated tokens -I- DXL: <Line:100> all done with 2 errors and 0 warnings c. -E- DXL: <Line:45> incorrectly concatenated tokens -I- DXL: <Line:100> all done with 1 error and 0 warnings 4. when I later execute: (&func)(str); a. program runs, but doesn't give output printed inside the functions: calling the func on 'funny' calling the func on 'funky' calling the func on 'flava' b. -E- DXL: <Line:46> incorrect use of identifier (func) -I- DXL: <Line:100> all done with 1 error and 0 warnings c. program runs, but doesn't give output printed inside the functions: calling the func on 'funny' calling the func on 'funky' calling the func on 'flava' */ |
|
![]() |
|
![]() |
|
Edited: 9-Oct-2003 at 22:38 by Dale Reed |
|
![]() |
|
![]() |
|
Hi Kip,
the thing, you are looking for is the undocumented addr_ function. This function can be used to convert function pointers into int and reverse. A sample code is in wizard/project/wizard.inc from Telelogic. Here is a part of it : Skip initList = create // List of Init fns ---------------------------- snip ------------------------------------------------------------------------ /******************************************************************** ** caller */ int caller(int fn()) { return fn() } /* caller */ /******************************************************************** ** init */ int init(int page) { int fn if (find(initList, page, fn)) { return caller(addr_ fn) } else { ack "Error: init function not found for page (init)" return -1 } } /* init */ /******************************************************************** ** add_wizard_page */ ------------------------------ snip ------------------------------------------------------- void add_wizard_page(int page, DB db, int init(), int next(), int helpid) { // "Adding wizard page: " page "" page = page /*- 1*/ // Translate page 1 to index 0 add_wizard_buttons(page, db, helpid) put(pageList, page, db) put(initList, page, addr_ init) put(nextList, page, addr_ next) } /* add_wizard_page */ As You can see, there is a Skip list with function pointers, wich are called from the init function. I think it should work with Arrays too. The only thing is, that you need a wrapper function (caller) wich calls your real function ... I hope this will help You and is in DOORs 5.2 available (I work with DOORs 7.0 SP1) Greetings Reik ------------------------- Evosoft GmbH for Siemens Industry Sector Berlin, Germany |
|
![]() |
FuseTalk Standard Edition v3.2 - © 1999-2009 FuseTalk Inc. All rights reserved.