Hello,
A couple days ago my friend (OOP guy) shows me what OOP was all about
in C++. This morning I figured I can do pretty much the same thing
with C (by putting function pointers in structures and using Macros).
I've gone pretty far but I'm running into problems because the function
pointers within the structures need an extra argument (a pointer to
that type of structure) so they know which data to operate on. Also, I
have to initialize all the functions pointers for every structure
object I define.
I'm trying to get rid of all this using Macros, and this is where I
need help.
I get "invalid type argument ->" as error message from my
compiler/preprocessor.
Here are the includes and macros:
---------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define InitFunctions(P ) {(P)->setname = nameset;
(P)->setlover = loverset;
(P)->setIQ = IQset;}
#define (P).NAME(S) (P).setname( (S), &(P) );
#define (P).LOVER(S, I) (P).setlover( (S), (I), &(P) );
#define (P).IQ(I) (P).setIQ( (I) , &(P) );
Here is my structure(simul ated class) template:
-----------------------------------------------
struct PersonTag
{
char name[40];
char loves[20][40];
int IQ;
char *(*setname)(con st char *, struct PersonTag *);
char *(*setlover)(co nst char *, int index, struct PersonTag *);
int (*setIQ)(const int, struct PersonTag *);
};
typedef struct PersonTag Person;
Here are the function definitions:
----------------------------------
char *nameset(const char *name, Person *P)
{
/* name = NULL signals read operation */
if(name)
strcpy(P->name, name);
return P->name;
}
char *loverset(const char *newlove, int index, Person *P)
{
/* newlove = NULL signals read operation */
if(newlove)
strcpy(P->loves[index], newlove);
return P->loves[index];
}
int IQset(const int IQ, Person *P)
{
/* IQ = 0 signals read operation */
if(IQ)
P->IQ = IQ;
return P->IQ;
}
Here is my main function:
-------------------------
int main(void)
{
Person Dan;
InitFunctions(D an);
Dan.NAME("Dan") ;
Dan.LOVER("Juli a", 0);
Dan.IQ(100);
printf("Name = %s\nFirst Lover = %s\n,IQ = %d\n",
Dan.NAME(NULL), Dan.LOVER(NULL, 0), Dan.IQ(0) );
return 0;
}
I am not too worried about buffer overflow or error checking at this
point (strcpy). My difficulties are in trying to "hide away" the
operations of: setting function pointers in the structure objects to
the proper functions AND passing extra structure pointer argument every
time a function is called.
I would think this is possible because the name of the structure is
always used when I call a function, and it's seems pointless that I
keep having to repeat the name.
Examples:
Bob.setlover("T eresa" , &Bob);
Bob.setIQ(120, &Bob);
As you can see, "Bob" comes twice for each call. Can anyone help me
with my macros or point me to another solution? Thanks 4 2226
"Deniz Bahar" <de*********@gm ail.com> wrote in message
news:11******** **************@ f14g2000cwb.goo glegroups.com.. . Hello,
A couple days ago my friend (OOP guy) shows me what OOP was all about in C++. This morning I figured I can do pretty much the same thing with C (by putting function pointers in structures and using Macros).
I've gone pretty far but I'm running into problems because the function pointers within the structures need an extra argument (a pointer to that type of structure) so they know which data to operate on. Also, I have to initialize all the functions pointers for every structure object I define.
I'm trying to get rid of all this using Macros, and this is where I need help. I get "invalid type argument ->" as error message from my compiler/preprocessor.
Sorry in advance that I don't answer to the question about your error
message but
I only answer to the OOP question:
If you need true objects: Use C++ or perhaps Objective-C.
I personally think that careful OOP style naming (see for example GLIB -
something like http://developer.gnome.org/doc/API/2...te-Arrays.html)
will be enough. No need for messy vtables etc.)
google for example for "object oriented vtable C". One hit: http://www.embedded.com/97/fe29712.htm
with respect,
Toni Uusitalo
Deniz Bahar wrote: Hello,
A couple days ago my friend (OOP guy) shows me what OOP was all about in C++. This morning I figured I can do pretty much the same thing with C (by putting function pointers in structures and using Macros).
OO in C is not OT round here.
I've gone pretty far but I'm running into problems because the function pointers within the structures need an extra argument (a pointer to that type of structure) so they know which data to operate on. Also, I have to initialize all the functions pointers for every structure object I define.
Hmmm, register new classes "somewhere" and give this somewhere only
a standard constructor which does only the setup of function pointers.
Then, CreateObject(Cl assName) is all you have to work with.
In special cases, it might even make sense to have sample class objects
which get memcpy()ed to new class objects.
The problem with passing the address of the object calling a method
cannot be circumvented.
There was a discussion about OOP in C some time ago on c.l.c where
I was involved. Use groups.google.
There was also a book about object oriented programming in ANSI C
mentioned. I cannot say anything about its quality; google for ooc.pdf.
I'm trying to get rid of all this using Macros, and this is where I need help. I get "invalid type argument ->" as error message from my compiler/preprocessor.
Here are the includes and macros: --------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h>
#define InitFunctions(P ) {(P)->setname = nameset; (P)->setlover = loverset; (P)->setIQ = IQset;}
Look at the do {} while 0 construct in the c.l.c FAQ #define (P).NAME(S) (P).setname( (S), &(P) );
#define (P).LOVER(S, I) (P).setlover( (S), (I), &(P) );
#define (P).IQ(I) (P).setIQ( (I) , &(P) );
This is not C.
You cannot fake ::, so use standard C macros.
About the interface: What do all your calls have in common?
Exactly. &P gets passed. So make it the same position in
all calls, i.e. the first argument.
Cheers
Michael Here is my structure(simul ated class) template: -----------------------------------------------
struct PersonTag { char name[40]; char loves[20][40]; int IQ;
char *(*setname)(con st char *, struct PersonTag *); char *(*setlover)(co nst char *, int index, struct PersonTag *); int (*setIQ)(const int, struct PersonTag *);
}; typedef struct PersonTag Person; Here are the function definitions: ----------------------------------
char *nameset(const char *name, Person *P) { /* name = NULL signals read operation */ if(name) strcpy(P->name, name); return P->name; }
char *loverset(const char *newlove, int index, Person *P) { /* newlove = NULL signals read operation */ if(newlove) strcpy(P->loves[index], newlove); return P->loves[index]; }
int IQset(const int IQ, Person *P) { /* IQ = 0 signals read operation */ if(IQ) P->IQ = IQ; return P->IQ; } Here is my main function: -------------------------
int main(void) { Person Dan; InitFunctions(D an);
Dan.NAME("Dan") ; Dan.LOVER("Juli a", 0); Dan.IQ(100);
printf("Name = %s\nFirst Lover = %s\n,IQ = %d\n", Dan.NAME(NULL), Dan.LOVER(NULL, 0), Dan.IQ(0) );
return 0; }
I am not too worried about buffer overflow or error checking at this point (strcpy). My difficulties are in trying to "hide away" the operations of: setting function pointers in the structure objects to the proper functions AND passing extra structure pointer argument every time a function is called.
I would think this is possible because the name of the structure is always used when I call a function, and it's seems pointless that I keep having to repeat the name.
Examples:
Bob.setlover("T eresa" , &Bob); Bob.setIQ(120, &Bob);
As you can see, "Bob" comes twice for each call. Can anyone help me with my macros or point me to another solution? Thanks
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Michael Mair wrote: Look at the do {} while 0 construct in the c.l.c FAQ
Make that while (0); sorry.
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Deniz Bahar wrote:
A couple days ago my friend (OOP guy) shows me what OOP was all about in C++. This morning I figured I can do pretty much the same thing with C (by putting function pointers in structures and using Macros).
I've gone pretty far but I'm running into problems because the function pointers within the structures need an extra argument (a pointer to that type of structure) so they know which data to operate on. Also, I have to initialize all the functions pointers for every structure object I define.
I'm trying to get rid of all this using Macros, and this is where I need help. I get "invalid type argument ->" as error message from my compiler/preprocessor.
Here are the includes and macros: --------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h>
#define InitFunctions(P ) {(P)->setname = nameset; (P)->setlover = loverset; (P)->setIQ = IQset;}
This should be done by the [pseudo] constructor.
Ditch the macros. Use inline static functions instead.
#define (P).NAME(S) (P).setname( (S), &(P) );
#define (P).LOVER(S, I) (P).setlover( (S), (I), &(P) );
#define (P).IQ(I) (P).setIQ( (I) , &(P) );
These aren't valid macro definitions.
Here is my structure(simul ated class) template: -----------------------------------------------
struct PersonTag { char name[40]; char loves[20][40]; int IQ; char *(*setname)(con st char *, struct PersonTag *); char *(*setlover)(co nst char *, int index, struct PersonTag *); int (*setIQ)(const int, struct PersonTag *);
}; typedef struct PersonTag Person;
Here are the function definitions: ----------------------------------
char *nameset(const char *name, Person *P) { /* name = NULL signals read operation */ if(name) strcpy(P->name, name); return P->name; }
char *loverset(const char *newlove, int index, Person *P) { /* newlove = NULL signals read operation */ if(newlove) strcpy(P->loves[index], newlove); return P->loves[index]; }
int IQset(const int IQ, Person *P) { /* IQ = 0 signals read operation */ if(IQ) P->IQ = IQ; return P->IQ; }
Here is my main function: -------------------------
int main(void) { Person Dan; InitFunctions(D an);
Dan.NAME("Dan") ; Dan.LOVER("Juli a", 0); Dan.IQ(100);
printf("Name = %s\nFirst Lover = %s\n,IQ = %d\n", Dan.NAME(NULL), Dan.LOVER(NULL, 0), Dan.IQ(0) );
return 0; }
I am not too worried about buffer overflow or error checking at this oint (strcpy). pMy difficulties are in trying to "hide away" the operations of: setting function pointers in the structure objects to the proper functions AND passing extra structure pointer argument every time a function is called.
I would think this is possible because the name of the structure is always used when I call a function, and it seems pointless that I keep having to repeat the name.
Examples:
Bob.setlover("T eresa" , &Bob); Bob.setIQ(120, &Bob);
As you can see, "Bob" comes twice for each call. Can anyone help me with my macros or point me to another solution?
The member function pointers don't buy you anything
unless you want to implement [run-time] polymorphism.
The way this is done is to create a Virtual function TABLE (VTABLE)
which contains pointers to the [actual] functions
and include a pointer to this table in each object.
Virtual functions reference the actual functions
through the pointers in the VTABLE.
cat main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 40
#define LOVERS 20
typedef struct Person {
const
void* pvft; // virtual function table pointer
char name[LENGTH];
size_t lovers;
char lover[LOVERS][LENGTH];
int IQ;
} Person;
typedef struct Person_virtualF unctionTable_t {
const char* (*name)(const Person*);
const char* (*love)(const Person*, size_t);
int (*IQ)(const Person*);
Person* (*newLove)(Pers on*, const char*);
int (*fprint)(FILE* , const Person*);
void (*destroy)(cons t Person*);
} Person_virtualF unctionTable_t;
const char*
ActualPerson_na me(const Person* const p) {
return p->name;
}
const char*
ActualPerson_lo ver(const Person* const p, size_t lover) {
return (lover < p->lovers)? p->lover[lover]: NULL;
}
int
ActualPerson_IQ (const Person* const p) {
return p->IQ;
}
Person*
ActualPerson_ne wLove(Person* const p, const char* const lover) {
if (NULL != lover)
if (p->lovers < LOVERS) {
strncpy(p->lover[p->lovers], lover, LENGTH);
p->lover[p->lovers][LENGTH-1] = '\0';
++(p->lovers);
}
return p;
}
int
ActualPerson_fp rint(FILE* const fp, const Person* const p) {
int characters = 0;
characters += fprintf(fp, "Name: %s\n", p->name);
if (0 < p->lovers) {
characters += fprintf(fp, "lover\tname\n" );
for (size_t lover = 0; lover < p->lovers; ++lover)
characters += fprintf(fp, "%3d\t%s\n" ,
lover, p->lover[lover]);
}
characters += fprintf(fp, "IQ: %d\n", p->IQ);
return characters;
}
void
ActualPerson_de stroy(const Person* const p) {
}
const Person_virtualF unctionTable_t
Person_virtualF unctionTable = {
ActualPerson_na me, ActualPerson_lo ver, ActualPerson_IQ ,
ActualPerson_ne wLove, ActualPerson_fp rint,
ActualPerson_de stroy };
Person
Person_create(
const char* const name, const char* const lover, int IQ) {
Person P;
P.pvft = (const void*)(&Person_ virtualFunction Table);
strncpy(P.name, name, LENGTH);
P.name[LENGTH-1] = '\0';
P.lovers = 0;
ActualPerson_ne wLove(&P, lover);
P.IQ = IQ;
return P;
}
// virtual functions
inline static const char*
Person_name(con st Person* const p) {
return ((Person_virtua lFunctionTable_ t*)(p->pvft))->name(p);
}
inline static const char*
Person_love(con st Person* const p, size_t lover) {
return ((Person_virtua lFunctionTable_ t*)(p->pvft))->
love(p, lover);
}
inline static int
Person_IQ(const Person* const p) {
return ((Person_virtua lFunctionTable_ t*)(p->pvft))->IQ(p);
}
inline static Person*
Person_newLove( Person* const p, const char* lover) {
return ((Person_virtua lFunctionTable_ t*)(p->pvft))->
newLove(p, lover);
}
inline static int
Person_fprint(F ILE* fp, const Person* const p) {
return ((Person_virtua lFunctionTable_ t*)(p->pvft))->
fprint(fp, p);
}
inline static void
Person_destroy( const Person* const p) {
((Person_virtua lFunctionTable_ t*)(p->pvft))->destroy(p);
}
int main(int argc, char* argv[]) {
const
Person Dan = Person_create(" Dan", "Julia", 100);
Person_fprint(s tdout, &Dan);
Person_destroy( &Dan);
return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o main main.c ./main
Name: Dan
lover name
0 Julia
IQ: 100
As you can plainly see,
my main program is much simpler
and works much better than yours.
The main difference between C and C++ is that
C++ does most of this stuff for you. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Christian |
last post by:
Hello,
As the subject says it, is there a way to simulate a special keypress in JS
? In my case, on loading an HTML page, i'd like to set the cursor at the end
of the input text of an <input type=text ...> object.
focus() sets the cusor at the beginning
Any idea ?
Christian.
|
by: JustSomeGuy |
last post by:
I need to log into a web page automatically.
The web page has a password text field and a login button.
(A form?)
How do I simulate that a user logged in and entered the password
and pressed the login button?
TIA.
|
by: dast |
last post by:
I want to simulate an input and post into a web page and than download
the web page that is opened after the correct input! The web page
exists of an user input form with userid and password, after input the
correct data and pressing the submit button another web page will be
opened.
I have tried to download the web page with the following code (I am
using the CAmHttpSocket class at
http://www.codeproject.com/internet/amhttputils.asp):
|
by: /* frank */ |
last post by:
I have to do a homework: make a CPU simulator using C language.
I have a set of asm instructions so I have to write a program
that should:
- load .asm file
- view .asm file
- do a step by step simulation
- display registers contents
I tried to search con google with no success.
|
by: johnny |
last post by:
On a form I would like to simulate a button click when the Enter is pressed.
My form is setup and it works if the delegate for the key pressed on the form
calls the delegate for the button pressed. But can we simulate a button click
instead?
This way if later the delegate is changed for the button, we don't forget to
do the changes on other events?
| |
by: Garry Freemyer |
last post by:
I'm trying to convert this macro to a c# function but I have a big problem.
It's on the LEFT side of an assignment statement and I am extremely
flustered over this one because I'm a little rusty and have been struggling
over this for days, not wanting to show all my ignorance in final desparate
plea for help which this is ...
Here is the macro ...
#define X(t,b) (sp->x)
|
by: diegocarpintero |
last post by:
I am writing a c# class which main purpose is to simulate the dialog
with a GUI-application.
The idea is that this class can simulate some user actions like mouse
clicks on buttons.
I have found the following possibilities to simulate it:
1) Use SendInput Function (user32.dll) (unmanaged code)
2) Use System.Windows.Forms.SendKeys (managed code)
|
by: =?Utf-8?B?UmljYXJkbyBRdWludGFuaWxsYQ==?= |
last post by:
how to simulate a different time zone?
¿is it possible by code to simulate that i am in a different time zone just
for to execute a few lines of code?
in my case i am in the time zone "Santiago/Chile" which is GMT-04, but for
to execute a few lines of code that demand time zone "GMT 0"
i need to change or simulate de time zone "GMT 0"
how can i do that?
|
by: c0mm3nt |
last post by:
Hi Guys.
I'm writing a web crawler (web spider) that crawl all links in a website.
My application is a Win32 App, written in C# with .Net framework 3.5.
Now I'm using HttpWebRequest an HttpWebResponse to communicate with the web server.
I also built my own Http Parser that can parse anything I want.
I found all link like "href", "src", "action"... in the parse.
But I can not solve one problem: Simulate Client Script in the page (like JS...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |