Function Pointers in a Structure?

G

gmtonyhoyt

It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.

Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?

This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.

Tony
 
M

Michael Mair

It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.

Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?

This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.

The person was talking about function pointers in structures;
this gives you your "class methods". Appropriate access macros
can make access to these "methods" slightly clearer.
You can fake single inheritance by including the parent struct
as first member into the child struct; if you access a pointer
to the child struct as a pointer to an ancestor, everything
still works. In much the same way you can effectively overwrite
parent methods of ancestors by storing another function pointer
in the child.
It is usually a good idea to have a base class every other class
is derived from; if you have a control word encoding the type of
the respective class, you have RTTI.
And so on. Just look for object oriented programming in C in the
newsgroups archives.


Cheers
Michael
 
R

Roger Leigh

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.

Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?

You can do single inheritance, virtual functions, polymorphism and
RTTI, interfaces/mixins, object properties and all sorts of OO stuff
in plain C. However, there are libraries to help you do it properly,
GObject being one of the most widely used:

http://developer.gnome.org/doc/API/2.0/gobject/index.html
http://www.le-hacker.org/papers/gobject/


Regards,
Roger

- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>

iD8DBQFDDi6PVcFcaSW/uEgRAqunAJ4uBUqYKUx/7z0pwUxpqVjKKHSGNACgts5W
qIWsX2tQiWYkUwPNaqjnm1I=
=tcwj
-----END PGP SIGNATURE-----
 
E

Emmanuel Delahaye

It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.

Well, sort of... The syntax is gory, because there is no implicit
'this' in C... All is explicit, thus gory...
Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?

This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.

What about Objective C?


--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair
 
I

Ian

This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.
Obvious question, why can't you use C++?

Ian
 
J

jacob navia

It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.

Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?

This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.

Tony

You can define interfaces like this:

// In a header file you do:
struct interface; // forward declaration
// Define a LIST data type for holding linked lists
typedef struct tagList {
struct interface * lpVtbl; // Pointer to the function table
// Data fields
struct tagList *PointerToLastElement;
struct tagList *FirstElement;
int NumberOfElements;
} LIST;

// Define the function table (methods)
struct interface {
int (*Append)(LIST *L,void *data);
void *(*First)(LIST *L);
void *(*Last)(LIST *L);
void *(*Remove)(LIST *L);
int (*Length)(LIST *L);
// Just an example. Many functions are missing
// But you get the idea.
};

// Now, in an implementation file you do:

static int Append(LIST *L,void *data)
{ // Implementation omitted }

static void *First(LIST *L)
{ // Implementation omitted }

static void *Last(LIST *L)
{ // Implementation omitted }

static void *Remove(LIST *L)
{ // Implementation omitted }

static int Length(LIST *L)
{ // Implementation omitted }

// Define a static struct interface holding
// function pointers to the implementation.
static struct interface {
First, Last,
Remove, Length
} MethodTable;

// Define the constructor.
LIST *newList(int NumberOfElements)
{
LIST *result;
result = malloc(sizeof(LIST));
if (result) {
memset(result,0,sizeof(LIST));
// assign the method table
result->lpVtbl = & MethodTable;
// assign the other fields
}
return result;
}

AND NOW (at last) you use it like this:

#include "list.h"
int main(void)
{
LIST *myList = newList(12);

myList->lpVtbl->Append(myList,"Element1");
myList->lpVtbl->Append(myList,"Element2");
int d = myList->lpVtbl->Length(myList); // Should be 2
}

This is quite powerful since you can at any time replace
those function pointers by a function of your own (subclassing)
but you can keep a copy of the function pointer to call the
original method either before or after or in between your
own subclassed method, what you can't do in C++.

C is more explicit than C++, and there is no compiler help.
This is less of a problem than what it seems at first sight,
and MUCH more powerful. You are in control. There is no
black box of a compiler to keep you from doing what you want.

Also, there are no rules other than the rules you decide to follow.

Of course this can be used constructively or can lead to code
that is impossible to follow. It is up to you.

For an example of this kind of programming see the source code
of the container library in lcc-win32.

http://www.cs.virginia.edu/~lcc-win32.
 
J

jacob navia

jacob said:
typedef struct tagList {
struct interface * lpVtbl; // Pointer to the function table
// Data fields
struct tagList *PointerToLastElement;
struct tagList *FirstElement;
int NumberOfElements;
} LIST;

Sorry that should have been
typedef struct tagListElement {
struct tagListElement *Next;
void *Data;
} ListElement;

typedef struct tagList {
struct interface * lpVtbl; // Pointer to the function table
// Data fields
ListElement *Last;
ListElement *First;
int NumberOfElements;
} LIST;

A LIST contains list elements, not LISTs.

jacob
 
G

gmtonyhoyt

Project leader doesn't want to use C++ for now. The project also
contains 5 year old code (All I've worked on) and I don't want to mix
and match just now. When I re-write the code, I may request I could do
everything in C++ but for now, I have to use C. The thing is, if I can
start using object-oriented practices in my code now, it may make the
transition easier later.

For everyone else, I want to say a big thanks for all this help. Now
to take time and absorb what you've given me so I can try and
understand it.

Tony
 
G

gmtonyhoyt

jacob said:
// Define the function table (methods)
struct interface {
int (*Append)(LIST *L,void *data);
void *(*First)(LIST *L);
void *(*Last)(LIST *L);
void *(*Remove)(LIST *L);
int (*Length)(LIST *L);
// Just an example. Many functions are missing
// But you get the idea.
};

// Now, in an implementation file you do:
static int Append(LIST *L,void *data)
{ // Implementation omitted }

// Define a static struct interface holding
// function pointers to the implementation.
static struct interface {
First, Last,
Remove, Length
} MethodTable;

The only thing that concerns me at this point, are multi-threaded
applications. Is this example multi-thread safe? I know this isn't
exactly a strict C problem at this point but, I was wondering if you
knew. The reason I ask this is, your creating a single instance of the
interface structure, MethodTable as a global and then assigning that to
each instance of the LIST structre someone creates and initalizes with
newList(). Would their be a problem or not?

Tony
 
J

jacob navia

The only thing that concerns me at this point, are multi-threaded
applications. Is this example multi-thread safe? I know this isn't
exactly a strict C problem at this point but, I was wondering if you
knew. The reason I ask this is, your creating a single instance of the
interface structure, MethodTable as a global and then assigning that to
each instance of the LIST structre someone creates and initalizes with
newList(). Would their be a problem or not?

Notice that in most cases the data in that structure is strictly
READ ONLY and that can be accesses from as many threads as you wish.

I would never modify the data structure directly but make a local copy,
then modify the copy, unless you want to make the change permanent for
all objects using it. It is up to you. In THAT case you need to access
that data structure using a guarded channel, typically a critical
section under windows, or a similar construct under other OS.
 
I

Ian

Project leader doesn't want to use C++ for now. The project also
contains 5 year old code (All I've worked on) and I don't want to mix
and match just now. When I re-write the code, I may request I could do
everything in C++ but for now, I have to use C. The thing is, if I can
start using object-oriented practices in my code now, it may make the
transition easier later.
Good reason.

It may be a bit old now, but one of best OO C toolkits I have used was
XView. It is quite small and well structured, you would learn a lot
from it. You can still get the source and the (very good) manual is
available from

http://www.oreilly.com/openbook/openlook/

Ian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,220
Latest member
MathewSant

Latest Threads

Top