Welcome to Telelogic Product Support
  Home Downloads Knowledgebase Case Tracking Licensing Help Telelogic Passport
Telelogic DOORS (steve huntington)
Decrease font size
Increase font size
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
Search Topic Search Topic
Topic Tools Topic Tools
Quick Reply Quick Reply
Subscribe to this topic Subscribe to this topic
E-mail this topic to someone. E-mail this topic
Bookmark this topic Bookmark this topic
View similar topics View similar topics
View topic in raw text format. Print this topic.
 11-Sep-2003 00:46
User is offline View Users Profile Print this message


Kip Kohn

Posts: 1
Joined: 11-Sep-2003

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'


*/

Report this to a Moderator Report this to a Moderator
 9-Oct-2003 15:44
User is offline View Users Profile Print this message


Dale Reed

Posts: 11
Joined: 13-Sep-2002




Edited: 9-Oct-2003 at 22:38 by Dale Reed
Report this to a Moderator Report this to a Moderator
 8-Mar-2004 12:51
User is offline View Users Profile Print this message


Reik Schroeder

Posts: 361
Joined: 28-Jul-2003

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
Report this to a Moderator Report this to a Moderator
Statistics
20925 users are registered to the Telelogic DOORS forum.
There are currently 1 users logged in.
The most users ever online was 15 on 15-Jan-2009 at 16:36.
There are currently 0 guests browsing this forum, which makes a total of 1 users using this forum.
You have posted 0 messages to this forum. 0 overall.

FuseTalk Standard Edition v3.2 - © 1999-2009 FuseTalk Inc. All rights reserved.