usage example for container_of in functions

I

InuY4sha

Yo, me again ^_^

say I have a structure of this type

typedef struct{
int data;
int *(*foo)(void *obj1, void *obj2);
}mystruct;

I'd like to know if and how I can use the function "container_of"
within foo, to track back the pointer of the allocated "mystruct"
instance.

Thanks,
R
 
K

Keith Thompson

InuY4sha said:
say I have a structure of this type

typedef struct{
int data;
int *(*foo)(void *obj1, void *obj2);
}mystruct;

I'd like to know if and how I can use the function "container_of"
within foo, to track back the pointer of the allocated "mystruct"
instance.

What is "container_of"?

[... google ...]

Ah, I see, it's a macro defined in the Linux kernel. You might want
to ask in a Linux-specific newsgroup.

I doubt that what you're trying to do is possible. Given a mystruct
object "obj", and given a pointer to the member "obj.foo" of that
object, you could compute a pointer to "obj". But within the function
to which obj.foo points, you don't have a pointer to foo.obj (unless
you pass it as an argument).
 
S

Seebs

Yo, me again ^_^

say I have a structure of this type

typedef struct{
int data;
int *(*foo)(void *obj1, void *obj2);
}mystruct;

I'd like to know if and how I can use the function "container_of"
within foo, to track back the pointer of the allocated "mystruct"
instance.

You can't, because you'd need to use it, not on the function pointed to
by the member foo, but on the member foo. Which you can't.

Likely workaround: Define the function with another argument, representing
the struct:

typedef struct mystruct {
int data;
int *(*foo)(void *obj1, void *obj2, struct mystruct *me);
} mystruct;
#define STRUCT_CALL(s, m, a, b) ((s)->(m)(a, b, (s)))

struct mystruct *blah;
STRUCT_CALL(blah, foo, &o1, &o2);

-s
 
S

Seebs

Ah, I see, it's a macro defined in the Linux kernel. You might want
to ask in a Linux-specific newsgroup.

You might think, but he's not actually asking about the Linux kernel per
se, but about a way to have embedded objects within structs. Think of it
used in a context like:

struct list { struct list *next; }

struct foo {
int i;
struct list l;
unsigned char *data;
};

You can iterate over a series of lists, then take the list and get a pointer
to the containing struct foo.

-s
 
I

InuY4sha

You can't, because you'd need to use it, not on the function pointed to
by the member foo, but on the member foo.  Which you can't.

Likely workaround:  Define the function with another argument, representing
the struct:

typedef struct mystruct {
  int data;
  int *(*foo)(void *obj1, void *obj2, struct mystruct *me);} mystruct;

#define STRUCT_CALL(s, m, a, b) ((s)->(m)(a, b, (s)))

struct mystruct *blah;
STRUCT_CALL(blah, foo, &o1, &o2);

-s

Yes I also thought to that workaround.. I just wanted to know if there
would be a cleaner / more transparent way to have some kind of "c++"
class polimorphysm where I can have a same function that adapt to the
context within which it's used...
 
S

Seebs

Yes I also thought to that workaround.. I just wanted to know if there
would be a cleaner / more transparent way to have some kind of "c++"
class polimorphysm where I can have a same function that adapt to the
context within which it's used...

Not really. You can sorta fake it up, but somewhere in there, you'd
probably be better off either switching to a design that fits C, or switching
to one of the OO C-like languages. (Of them, I like Objective-C best,
Java next best, and C++ least.)

-s
 
N

Nick

InuY4sha said:
Yes I also thought to that workaround.. I just wanted to know if there
would be a cleaner / more transparent way to have some kind of "c++"
class polimorphysm where I can have a same function that adapt to the
context within which it's used...

The problem as I see it (having been pointed at something very similar
to this yesterday) is that in your case by the time you're in the
function you have no knowledge at all of how you got there. If you
could guarantee that any of the parameters were any part of the
structure (so, say, obj1 was always a pointer to the int data) then you
could mess around with offsetof (which is all that container_of does) to
get back to the top of the structure. But you need to actually have the
structure in some way - there's no way I know (standard or not) to
distinguish between these cases (which is what I think you're trying
to do):

foo(datap1,datap2);
mystruct->foo(datap1,datap2);

After all, somewhere you actually have defined foo - it's not in the
structure - and in both cases it's that same actual code, at the same
actual address, that's being called.
 

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,981
Messages
2,570,187
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top