473,394 Members | 1,715 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

problem with function pointers

I have two classes:
class OntologyParser
{
...

protected:

virtual void startElement(void *userData, const char *name, const
char **atts);
virtual void endElement(void *userData, const char *name);
virtual void charData( void *userData, const XML_Char *s, int len );

....
public:
void initXMLParse(const string& fname);
.....
};

This class is a base class for

class ProtegeOntologyParser : public OntologyParser
{
public:
inline ProtegeOntologyParser(const string& strFileName)
{
initXMLParse(strFileName);
}

};

I am using G++ on RedHat 9.0 Linux with Expat library.

The initXMLParse function is common to all (here just
ProtegeOntologyParser) derived classes hence I want to keep that in
parent class. The functions startElement, endElement and charData must
be implemented separately by all derived classes.

However the problem is expat needs call backs setup for startElement,
endElement and charData functions from within initXMLParse like this:

void OntologyParser::initXMLParse(const string& fname)
{
char buffer[BUFSIZ];
int len;
int done;
int depth = 0;

//Get the Parser
XML_Parser parser = XML_ParserCreate(NULL);

//User Data Handler
XML_SetUserData(parser, &depth);

//Element Level Handler
XML_SetElementHandler(parser, startElement, endElement);

//Set What to do with the data
XML_SetCharacterDataHandler( parser, charData );

....
}

But the functions that I pass there as argument must be the functions
of derived classes and right function addresses should be passed based
upon which object was responsible for invoking initXMLParse().

As you know ISO C++ forbids somthing like &(this->charData)
Secondly i do not want to make those 3 function static. and they must
be "virtual" in the base class so that all derived classes are forced
to implement them.

How can I pass those arguments?

Jul 23 '05 #1
1 1667
"TheOne" <su****************@gmail.com> wrote...
I have two classes:
class OntologyParser
{
...

protected:

virtual void startElement(void *userData, const char *name, const
char **atts);
virtual void endElement(void *userData, const char *name);
virtual void charData( void *userData, const XML_Char *s, int len );

....
public:
void initXMLParse(const string& fname);
.....
};

This class is a base class for

class ProtegeOntologyParser : public OntologyParser
{
public:
inline ProtegeOntologyParser(const string& strFileName)
{
initXMLParse(strFileName);
}

};

I am using G++ on RedHat 9.0 Linux with Expat library.

The initXMLParse function is common to all (here just
ProtegeOntologyParser) derived classes hence I want to keep that in
parent class. The functions startElement, endElement and charData must
be implemented separately by all derived classes.

However the problem is expat needs call backs setup for startElement,
endElement and charData functions from within initXMLParse like this:

void OntologyParser::initXMLParse(const string& fname)
{
char buffer[BUFSIZ];
int len;
int done;
int depth = 0;

//Get the Parser
XML_Parser parser = XML_ParserCreate(NULL);

//User Data Handler
XML_SetUserData(parser, &depth);

//Element Level Handler
XML_SetElementHandler(parser, startElement, endElement);

//Set What to do with the data
XML_SetCharacterDataHandler( parser, charData );

....
}

But the functions that I pass there as argument must be the functions
of derived classes and right function addresses should be passed based
upon which object was responsible for invoking initXMLParse().

As you know ISO C++ forbids somthing like &(this->charData)
Secondly i do not want to make those 3 function static.
But how would expat call them? It requres them to be callbacks of some
particular signature which probably does not have anything to do with
your classes. You have no choice but to make them static.
and they must
be "virtual" in the base class so that all derived classes are forced
to implement them.
The derived classes are not going to be forced unless those functions
are declared pure.
How can I pass those arguments?


Make the three functions static. Let expat pass the 'userdata' as
void* and static_cast it to your base class in each function. Then
call your "real" processing functions, which should be virtual, using
that base class pointer. The derived function should be called.

---------------------------------------
struct Caller { // your expat emulator
void (*int_callback)(void*,int);
void (*double_callback)(void*,double);
void* ptr;

void init_ptr(void* p) { ptr = p; }
void init_int_cb(void (*icb)(void*,int)) { int_callback = icb; }
void init_dbl_cb(void (*dcb)(void*,double)) { double_callback =
dcb; }

void do_something() {
int_callback(ptr, 666);
double_callback(ptr, 3.1415926);
int_callback(ptr, 42);
}
};

struct Base {
Caller *caller;

Base() : caller(new Caller) { caller->init_ptr(this); }
virtual ~Base() { delete caller; }
Base(const Base& b) : caller(new Caller(*b.caller)) {}

void init_caller();

static void foo_callback(void*, int);
static void bar_callback(void*, double);
virtual void foo(int) = 0;
virtual void bar(double) = 0;

private:
Base& operator =(const Base&);
};

#include <iostream>
using std::cout;

struct Derived : Base {
virtual void foo(int a) { cout << "Derived::foo(" << a << ")\n"; }
virtual void bar(double d) { cout << "Derived::bar(" << d <<
")\n"; }
};

void Base::foo_callback(void* ptr, int a) {
Base *p = static_cast<Base*>(ptr);
p->foo(a);
}

void Base::bar_callback(void* ptr, double d) {
Base *p = static_cast<Base*>(ptr);
p->bar(d);
}

void Base::init_caller() {
caller->init_int_cb(foo_callback);
caller->init_dbl_cb(bar_callback);

caller->do_something();
}

int main() {
Base *pb = new Derived;
pb->init_caller();
delete pb;
}
---------------------------------------
V
Jul 23 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: luigi | last post by:
Hi, I am trying to speed up the perfomance of stl vector by allocating/deallocating blocks of memory manually. one version of the code crashes when I try to free the memory. The other version...
13
by: Joseph | last post by:
I was doing my assignment,but encountered a problem at last step!!!!!! for easy reading, i ommited lots of other things //=====================code begin================================...
3
by: Markus Dehmann | last post by:
I have a class "Data" and I store Data pointers in an STL set. But I have millions of inserts and many more lookups, and my profiler found that they cost a lot of runtime. Therefore, I want to...
8
by: Mantorok Redgormor | last post by:
I have ran into a problem where I have a struct that has a member which contains a pointer to function and is initialized to a function in the initializer list. With my array of structs of this...
2
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c...
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
11
by: Michael | last post by:
Hi, I am trying to get an idea of how function pointers work. I have the following: #include <stdio.h> void do_stuff(int*,int,void*); void getInt(int*); void showInt(int*);
57
by: Robert Seacord | last post by:
i am trying to print the address of a function without getting a compiler warning (i am compiling with gcc with alot of flags). if i try this: printf("%p", f); i get: warning: format %p...
14
by: Frank | last post by:
Hello everyone, I am having trouble overloading the < operator for an assignment. I use a struct that contains information and I would like to sort this structure using STL sort with my own...
15
by: arnuld | last post by:
-------- PROGRAMME ----------- /* Stroustrup, 5.6 Structures STATEMENT: this programmes *tries* to do do this in 3 parts: 1.) it creates a "struct", named "jd", of type "address". 2. it...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.